2009-10-24 30 views
11

我已經在一個進程上完成了fork和exec(),但是我想在後臺運行它。我怎樣才能做到這一點? 我可以避免在它上面調用waitpid,但是這個過程永遠坐在那裏,等待將它的狀態返回給父對象。有沒有其他方法可以做到這一點?如何在C的後臺執行()一個進程?

回答

5

捕獲SIGCHLD並在處理程序中調用wait()。如果你忽略SIGCHLD,內核會自動清理殭屍進程(這是你在ps中看到的)。如果你忽略了SIGCHLD,內核會自動清理殭屍進程(這是你在PS中看到的)。這是一個很好的功能,但不便攜。

+0

這是實施最乾淨的解決方案。謝謝! – 2009-10-24 19:38:33

+0

對於將來出現同樣問題的程序員,下面是我在「UNIX環境下的高級編程」的第293頁中找到的內容: SIGCHLD 只要進程終止或停止,就會將SIGCHLD信號發送給父進程。默認情況下,這個信號被忽略,所以如果父母想要在孩子的狀態改變時得到通知,父母必須捕獲這個信號。信號捕獲函數中的正常操作是調用其中一個等待函數來獲取子進程ID和終止狀態。 在這種情況下,我只需要像liw.fi這樣的一行提示: waitpid(-1,&status,WNOHANG | WUNTRACED); – 2009-10-24 19:47:00

-1

叉創建後臺線程,然後執行。看到這個網站上的一個愚蠢的問題:Can we start a background process using exec() giving & as an argument?

+0

是的,我看到了這個問題,但它仍然沒有回答我原來的問題。當然,我可以避免等待電話,但這個過程永遠坐在那裏。每次運行ps -al時我都可以看到它。 – 2009-10-24 19:00:36

+0

我不認爲過去的問題的答案實際上回答了這個問題(因爲aditya也抱怨); Avi給出了正確的答案。此外,我對過去的問題的答案實際上回答了這個過去的問題持懷疑態度(因爲OP也想創建一個後臺進程,沒有人告訴他有關雙叉的問題)。 – 2009-10-24 19:12:18

0

waitpid(-1, &status, WNOHANG)可能會做你所需要的:它應該立即返回,如果沒有子進程退出。或者,您可以偵聽SIGCHLD信號。

+0

這不是一個好策略 - 除非父進程準備好一遍又一遍地完成(否則你最終還是以殭屍結束)。 – 2009-10-24 19:13:29

+0

不幸的是,我得到了馬丁預測的結果,但直到那時它肯定聽起來很好。 – 2009-10-24 19:20:42

+0

這一切都取決於父進程的結構。有時偶爾進行輪詢更容易,而不是抓住SIGCHLD。 – 2009-10-25 06:32:55

4

我認爲你要做的是創建一個守護進程。閱讀維基百科上的this鏈接以獲得解釋。

一個例子(從史蒂芬的UNIX環境高級編程)製作的過程的守護程序是:

#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 

int daemon_int(void) 
{ 
    pid_t pid; 
    if ((pid = fork()) < 0) 
     return (-1) ; 
    else if (pid != 0) 
     exit(0) ; /* The parent process exits */ 
    setsid() ; /* become session leader */ 
    chdir("/") ; /* change the working dir */ 
    umask(0) ; /* clear out the file mode creation mask */ 
    return(0) ; 
} 

當然這並假設一個類似Unix的操作系統。

因此,您的程序包含上述功能,並在運行後立即調用它。然後從父進程中解除它,並將繼續運行直到它終止或被殺死。

+0

嗯,仔細閱讀這個問題讓我覺得阿維可能會有答案。或者你可以讓第一個孩子成爲一個等待孫子終結的守護進程。所以喲打破父母和孩子之間的聯繫,所以父母可以終止而不導致孩子和孫子退出。 – Jackson 2009-10-24 19:19:57

+0

如果你想這樣做,你也希望你的原始進程調用wait()來獲得它的孩子。由於子進程會很快退出(在分支孫子之後),您的原始進程不會在wait()中長時間阻塞。 – 2009-10-24 19:20:46