Fork ()가 호출하는 모든 아동 프로세스가 완료 될 때까지 기다리는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/279729

문제

나는 여러 프로세스를 포킹하고 있으며 전체 작업을 완료하는 데 시간이 얼마나 걸리는지, 즉 모든 프로세스가 완료 될 때입니다. 모든 아동 프로세스가 종료 될 때까지 부모 프로세스를 기다리는 방법에 대해 조언하십시오. 적절한 순간에 타이머를 멈추고 싶습니다.

다음은 내가 사용하는 코드입니다.

#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
도움이 되었습니까?

해결책

나는 "else // 부모"라인 후에 모든 것을 For Loop 외부로 움직입니다. 포크 루프 후에는 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);
        }
    }
}

이것은 순서대로 어떤 프로세스가 실패했는지 알려주지 않지만,주의를 기울이면 Code를 추가하여 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).

모든 어린이가 설명 될 때까지 루프에서 대기 (또는 Waitpid)를 호출하십시오.

이 경우, 모든 프로세스는 어쨌든 동기화되지만 일반적으로 더 많은 작업을 수행 할 수있는 경우 (예 : 작업자 프로세스 풀)가 최초의 사용 가능한 프로세스 상태가 변경 될 때 반환되므로 대기가 선호됩니다.

나는 믿는다 시스템 호출을 기다립니다 당신이 찾고있는 것을 성취 할 것입니다.

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

올바른 순서로 기다리지는 않지만 마지막 아이가 죽은 직후에 멈출 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top