2009-10-02 3 views
12

내 프로그램에서 유한 한 while 루프에서 자식 프로세스를 병렬 처리하고 각각에 exec를 수행하고있다. 부모 프로세스가 모든 자식이 종료 된 후에 만 ​​실행을 다시 시작하기를 원합니다. 어떻게해야합니까?부모가 실행을 재개하기 전에 모든 자식 프로세스를 기다린다. UNIX

나는 여러 가지 접근법을 시도했다. 한 접근법에서, 나는 while 루프 후에 Parent를 멈추고 waitpid가 ECHILD (자식은 남아 있지 않음)를 반환했을 때만 SIGCHLD handler로부터 어떤 조건을 보냈지 만, 부모가 모든 프로세스를 fork하기 전에라도이 접근법에서 직면하고있는 문제는 retStat가된다. -1

void sigchld_handler(int signo) { 
     pid_t pid; 
     while((pid= waitpid(-1,NULL,WNOHANG)) > 0); 
     if(errno == ECHILD) { 
      retStat = -1; 
     } 
    } 

    **//parent process code** 
    retStat = 1; 
    while(some condition) { 
     do fork(and exec); 
    } 

    while(retStat > 0) 
     pause(); 
//This is the point where I want execution to resumed only when all children have finished 

답변

21

: 더 이상 아이들이 없을 때까지

while (pid = waitpid(-1, NULL, 0)) { 
    if (errno == ECHILD) { 
     break; 
    } 
} 

프로그램은 루프에서 정지한다. 그러면 프로그램이 종료되고 프로그램이 계속됩니다. 추가 보너스로 아이들이 실행되는 동안 루프는 waitpid에서 차단되므로 기다리는 동안 바쁜 루프가 필요하지 않습니다.

wait(NULL)waitpid(-1, NULL, 0)과 같아야합니다. SIGCHLD에서해야 할 일이 없다면 SIG_IGN으로 설정할 수 있습니다.

+0

WNOHANG 옵션을 주어야합니다. 왜냐하면 SIGCHLD 신호를 거의 동시에 전달하는 많은 자식이 있고 UNIX에서 신호가 대기열에 있지 않기 때문에 0을 사용하면 하나의 신호 만 잡을 수 있기 때문에 좀비가 돌아 다닐 지어다. – avd

+0

비트를 추가하기 만하면 -1이 자식 pid를 확인합니다 (명확성을 위해 WAIT_ANY도 사용할 수 있음). – amischiefr

+0

@aditya : 좀비 프로세스는 wait() (또는 wait_pid())를 호출하기 만하면됩니다. 그렇게하면 신호를 포착했는지 여부와 관계없이 사라질 것입니다. 따라서 fork() 루프 이후의 wait() 루프는 모든 좀비를 청소합니다. –

0

나는 waitpid() 호출을 사용해야한다고 생각합니다. "모든 하위 프로세스"를 기다릴 수 있으므로 적절한 횟수만큼 수행하면 황금이어야합니다.

하기 전에, 당신은 무차별 접근 자녀의 PID의 각각에 waitpid()NOHANG 옵션을하고, 루프에 앉아 다음 잠시 동안 연기를 할 수있는 (보장 사항에 대해 확실하지) 실패하는 경우 다시. 대신 다음과 같이 모든 프로세스를 포크 후 루프를 작성하지 왜, 신호 처리기에서 waitpid를 호출

+0

코드를 참조하십시오, 내가 말한 것과 똑같은 일을했습니다. – avd

+0

@aditya : 아뇨, 제 의견은 jborque가 제안한대로 신호 처리기를 사용하는 것에 대해 아무 말도하지 않았 음을 의미합니다. – unwind