2011-05-08 49 views
0

我想寫一個程序,檢查退出的子進程,並重新啓動它們,如果他們退出。它需要在進程退出時重新啓動進程,而不必等待任何其他進程退出。我有點迷路。以下是我迄今爲止所做的代碼。它沒有完成或沒有改變,真的。但也許有人可以指出我正確的方向?檢查POSIX中退出的子進程?

for(int ifile = 1; ifile < 4; ifile++){ 

    child_pid[ifile - 1] = vfork(); 

    if(child_pid[ifile - 1] == -1){ 
     cerr << "fork error on " << argv[ifile] << endl; 
    } 
    else if(child_pid[ifile - 1] == 0){ 
     execl(argv[ifile], argv[ifile], NULL); 
    } 
} 

for(int index = 0; index < 3; index++){ 
    do{ 
     wait_pid = waitpid(child_pid[index], &status, WUNTRACED); 
     if(WIFEXITED(status)){ 
      count++; 
      child_pid[index] = vfork(); 
      if(child_pid[index] == -1){ 
       cerr << "rescheduled process error" << endl; 
       return -1; 
      } 
      else if(child_pid[index] == 0){ 
       cout << "Rescheduling " << argv[index + 1] << endl; 
       execl(argv[index + 1], argv[index + 1], NULL); 
      } 
     } 
    }while(count != 4); 
} 

回答

3

您的方法存在的問題是,您將阻止waitpid,直到第1個孩子死亡,其他任何人都可能在此期間死亡。 (1)使用wait()而不是waitpid()。(1)使用wait()而不是waitpid()。這將處理任何孩子,但會阻止。 (2)使用waitpid()和WNOHANG標誌在循環時輪詢死亡的孩子。 (3)建立一個信號處理程序並捕獲SIGCHILD信號。將waitpid/WNOHANG循環放入你的處理程序中,但是要在其外部重新啓動。

E.G. Handler做類似於:

while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) 
    { 
     //set a flag or whatever; not wise to fork/exec in handler 
    } 
2

我不確定爲什麼要選擇WUNTRACED選項。它說「已停止」的地方,我很確定它意味着與暫停而不是退出一樣。

兩種可能的方法:

而不是循環,只是做:

pid_t pid = wait(); 

它會阻止,直到進程結束。

或者,將第三個參數更改爲waitpid(),從WUNTRACED更改爲WNOHANG。這將讓它在不阻塞的情況下測試每個進程。在這種情況下,您可能需要在每次循環結束時通過循環添加一個小睡眠。