2012-02-06 75 views
1

尋找fork一個進程,在C++中,它不會掛起它的父進程 - 它的父進程是一個守護進程並且必須保持運行。如果我在分叉進程中等待()分叉execl不會defunt - 但是 - 它也將掛起應用程序 - 不等待修復應用程序掛起 - 但命令成爲defant。C++ fork,無需等待,解除execl

if((pid = fork()) < 0) 
    perror("Error with Fork()"); 
else if(pid > 0) { 
    //wait here will hang the execl in the parent 
    //dont wait will defunt the execl command 
    //---- wait(&pid); 
    return ""; 
} else { 
    struct rlimit  rl; 
    int     i; 

    if (rl.rlim_max == RLIM_INFINITY) 
     rl.rlim_max = 1024; 

    for (i = 0; (unsigned) i < rl.rlim_max; i++) 
     close(i); 

    if(execl("/bin/bash", "/bin/bash", "-c", "whoami", (char*) 0) < 0) perror("execl()"); 
    exit(0); 
} 

如何,我可以用叉子叉execl的無等待(& PID),其中EXECL的命令不會倒閉?

UPDATE 由叉

signal(SIGCHLD, SIG_IGN); 

在基於公認的答案更兼容的解決方案以我有限的技能還是工作之前添加下列固定。謝謝!

回答

5

默認情況下,wait和朋友等待進程退出,然後收穫。如果沒有孩子退出,您可以撥打waitpidWNOHANG立即返回。

死亡/「殭屍」進程將一直坐到你wait上。所以,如果你在後臺運行它,你必須安排由任何一種方式最終獲得它:

  • 嘗試waitpidWNOHANG常規:int pid = waitpid(-1, &status, WNOHANG)
  • 安裝的信號處理程序SIGCHLD通知其退出時

此外,POSIX.1-2001下,你可以使用sigaction設置SA_NOCLDWAITSIGCHLD。或者將其操作設置爲SIG_IGN。舊系統(包括Linux 2.4.x,但不包括2.6.x或3.x)不支持這一點。

檢查您的系統聯機幫助頁,或替代wait in the Single Unix Specification。 Single Unix Spec還提供了一些有用的代碼示例。 SA_NOCLDWAIT記錄在sigaction

+0

最簡單的解決方案是添加一個信號(SIGCHLD,SIG_IGN);在我的前叉之前 - 我嘗試了幾乎所有其他選項,這些選項似乎超出了我的有限技能。我會繼續努力以防萬一人想要使用2.4.x. – 2012-02-07 02:18:57

0

我認爲一個信號處理程序是最好的方式,如圖所示。我想指出另一種處理方式:分叉兩次,讓孩子離開,而孫子會撥打execl。然後通過初始化進程清理已停用的進程。

+0

我試過雙叉,它沒有工作出於某種原因在我的情況。還建議雙叉在另一個棧的問題,我有,但是普遍認爲這不完全是這樣做 – 2012-02-07 02:19:45

+0

我會同意,這就是爲什麼我認爲信號處理器是更好的最優化的方式,但我想我會提到它。 – 2012-02-07 13:17:59