我正在分配许多进程,我想测量完成整个任务所需的时间,即分叉完成所有进程的时间。请告知如何让父进程等到所有子进程终止?我想确保在合适的时刻停止计时器。
这是我使用的代码:
#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
答案 0 :(得分:22)
我会在for循环之外的“else // parent”行之后移动所有内容。在forx循环之后,用waitpid做另一个for循环,然后停止时钟并完成剩下的工作:
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返回状态,那么你将不得不相应地更改错误检查。
使用wait的另一种选择:
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数组中查找并获取索引。
答案 1 :(得分:13)
最简单的方法是
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)
。
答案 2 :(得分:4)
在循环中调用wait(或waitpid),直到考虑所有子项为止。
在这种情况下,所有进程都在进行同步,但通常情况下等待是可以完成更多工作的时候(例如工作进程池),因为它会在第一个可用进程状态发生变化时返回。
答案 3 :(得分:3)
我相信wait system call将会实现您的目标。
答案 4 :(得分:0)
for (int i = 0; i < pidCount; i++) {
while (waitpid(pids[i], NULL, 0) > 0);
}
它不会以正确的顺序等待,但它会在最后一个孩子死后不久停止。