如何等待fork()调用的所有subprocess完成?

我分叉了许多进程,并且要测量完成整个任务需要多长时间,即完成所有进程分叉的时间。 请告知如何让父进程等待,直到所有的subprocess终止? 我想确保我在适当的时候停止计时器。

这是作为我使用的代码:

#include <iostream> #include <string> #include <fstream> #include <sys/time.h> #include <sys/wait.h> using namespace std; struct timeval first, second, lapsed; struct timezone tzp; int main(int argc, char* argv[])// query, file, num. of processes. { int pCount = 5; // process count gettimeofday (&first, &tzp); //start time pid_t* pID = new pid_t[pCount]; for(int indexOfProcess=0; indexOfProcess<pCount; indexOfProcess++) { pID[indexOfProcess]= fork(); if (pID[indexOfProcess] == 0) // child { // code only executed by child process // magic here // The End exit(0); } else if (pID[indexOfProcess] < 0) // failed to fork { cerr << "Failed to fork" << endl; exit(1); } else // parent { // if(indexOfProcess==pCount-1) and a loop with waitpid?? gettimeofday (&second, &tzp); //stop time if (first.tv_usec > second.tv_usec) { second.tv_usec += 1000000; second.tv_sec--; } lapsed.tv_usec = second.tv_usec - first.tv_usec; lapsed.tv_sec = second.tv_sec - first.tv_sec; cout << "Job performed in " <<lapsed.tv_sec << " sec and " << lapsed.tv_usec << " usec"<< endl << endl; } }//for }//main 

Solutions Collecting From Web of "如何等待fork()调用的所有subprocess完成?"

我会把所有的东西都放在for循环之外的“else // parent”之后。 在叉子循环之后,用waitpid做另一个循环,然后停下来休息一下:

 for (int i = 0; i < pidCount; ++i) { int status; while (-1 == waitpid(pids[i], &status, 0)); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { cerr << "Process " << i << " (pid " << pids[i] << ") failed" << endl; exit(1); } } gettimeofday (&second, &tzp); //stop time 

我假设如果子进程无法正常退出,状态为0,那么它没有完成其工作,因此测试未能产生有效的计时数据。 显然,如果子进程应该被信号杀死,或者退出非0返回状态,那么你就必须相应地改变错误检查。

另一种使用等待:

 while (true) { int status; pid_t done = wait(&status); if (done == -1) { if (errno == ECHILD) break; // no more child processes } else { if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { cerr << "pid " << done << " failed" << endl; exit(1); } } } 

这个不会告诉你哪个进程顺序失败,但是如果你在意的话,你可以添加代码在pids数组中查找并获取索引。

最简单的方法是做

 while(wait() > 0) { /* no-op */ ; } 

如果wait()由于某种原因而失败,那么这将不起作用,除了没有孩子的事实。 所以有一些错误检查,这成为

 int status; [...] do { status = wait(); if(status == -1 && errno != ECHILD) { perror("Error during wait()"); abort(); } } while (status > 0); 

另请参阅手册页wait(2)

在一个循环中调用wait(或waitpid),直到所有的孩子都被占了。

在这种情况下,无论如何所有的进程都在同步,但是通常在进行更多的工作(比如工作进程池)时,首选等待,因为当第一个可用的进程状态改变时它会返回。

我相信等待系统调用将完成你正在寻找的东西。

 for (int i = 0; i < pidCount; i++) { while (waitpid(pids[i], NULL, 0) > 0); } 

它不会以正确的顺序等待,但在最后一个孩子死后不久就会停止。