2017-03-13 38 views
0

是否有Linux或POSIX方法指示一個進程不會變成殭屍,當它完成,並且父母不呼叫waitpid()讓孩子進程不殭屍,直到waitpid

我知道,父進程,我們可以使用SA_NOCLDSTOPSIGCHLD處理程序,但因爲父母忙,SIGCHLD是使用了其他的東西,是不是在我的情況選擇。

如果我對退出代碼不感興趣,有沒有辦法將特定的子進程標記爲悄悄死亡?

回答

0

你總是需要等待子進程,但是如果你遵循這個程序,那麼你可以等待一個快速死亡的子進程,讓init繼承你的「真實」進程。 Init會爲你整理。

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 

void main(void) { 
    int ret; 
    pid_t child1; 
    pid_t child2; 
    int status; 

    child1 = fork(); 
    if (child1 == -1) { 
     /* error */ 
     exit(1); 
    } 

    if (child1 == 0) { 
     /* in the child... we create a new session, and then re-fork */ 
     setsid(); 

     child2 = fork(); 
     if (child2 == -1) { 
      exit(1); 
     } 

     if (child2 == 0) { 
      /* call execve() or a friend */ 
      ret = execlp("sleep", "sleep", "6", NULL); 

      /* we should _never_ get here - unless the execlp() fails */ 
      fprintf(stderr, "execlp() returned: %d\n", ret); 
      exit(1); 
      for(;;); 
     } 

     sleep(2); 

     /* success ... child1 dies here */ 
     exit(0); 
    } 

    sleep(4); 

    ret = waitpid(child1, &status, 0); 
    if (ret != 0) { 
     /* unfortunately we can only determine the state of our 'proxy' process... 
     * to get any further information/the child-child PID, then you'll need to use a pipe to share the information */ 
     fprintf(stderr, "waitpid() returned %d\n", ret); 
    } 

    sleep(4); 

    return; 
} 

各種睡眠持續應該讓你看到下面的事件(看top或東西)。

步驟1

所有進程啓動,所有鏈接作爲你的shell

  • 17336的孩子 - 我的殼
  • 21855 - 應用程序
  • 21856 - Child1(代理程序)
  • 21857 - Child2(有用的子進程)

top輸出:

attie 17336 17335 0 16:04 pts/36 00:00:00 -bash 
attie 21855 17336 0 16:34 pts/36 00:00:00 ./test 
attie 21856 21855 0 16:34 ?  00:00:00 ./test 
attie 21857 21856 0 16:34 ?  00:00:00 sleep 6 

步驟2

Child1模具,並且變成殭屍/被禁,CHILD2得到由init繼承(PID 1)

attie 17336 17335 0 16:04 pts/36 00:00:00 -bash 
attie 21855 17336 0 16:34 pts/36 00:00:00 ./test 
attie 21856 21855 0 16:34 ?  00:00:00 [test] <defunct> 
attie 21857  1 0 16:34 ?  00:00:00 sleep 6 

步驟3

Child1得到由呼叫父清理到waidpid()

attie 17336 17335 0 16:04 pts/36 00:00:00 -bash 
attie 21855 17336 0 16:34 pts/36 00:00:00 ./test 
attie 21857  1 0 16:34 ?  00:00:00 sleep 6 

步驟4

CHILD2死亡,並得到由init清理

attie 17336 17335 0 16:04 pts/36 00:00:00 -bash 
attie 21855 17336 0 16:34 pts/36 00:00:00 ./test