2010-12-12 59 views
0

工作,在這種情況下,我寫了一個簡單PROG:Fork,exec - > man。不能正確

int main() 
{ 
    pid_t chpid; 
    chpid=fork(); 
    if(chpid==0) // child 
    { 
    sleep(2); 
    execlp("/usr/bin/man","/usr/bin/man","ps",NULL); 
    printf("still alive\n"); 
    } 
    else 
    { 
    printf("parent goes down\n"); 
    } 
    return 0; 

} 

在運行父母去世&在2秒鐘內我得到:/usr/bin/man: command exited with status 1: pager -s

爲什麼會這樣運行的?絕對的問題是父母的死亡,如果我添加(1)在父母的代碼中一切都很好。

我寫了一個測試編程,每個時間段都將一些字符串寫入標準輸出。有用。看起來很奇怪。

回答

0

所以。一個小小的研究表明,外殼,開始我的過程,設置控制終端(我的過程)setpgid()。當它死亡時,shell會再次調用setpgid(),儘管所有的孩子都是我的proc所編輯的fork。所以他們已經是守護神了。正如我發現的,守護進程也可以執行一些輸出例程,但是它們並不一定能夠成功。也許是,也許不是。這就是爲什麼孩子在父母去世後仍然可以做出輸出的原因(例如,如果我掏出一個簡單的piriodical writeong hello world program)。而且男人明白,他的產量會隨之下降,並開始恐慌。這是我看到它的方式。

至於strace,這很簡單:strace在我的程序的所有生命週期中都還活着,所以對於那個輸出沒有問題。

0

使用wait(3p)等待孩子死亡。

+0

問題是爲什麼它不起作用,不僅僅是爲了解決它。 – DimG 2010-12-12 15:11:39

1

通過在孩子跑步時從家長處退出,您剛剛將孩子奉獻給了孩子。它的守護進程和分叉沒有控制終端,這是尋呼機運行的要求(我相信pager -sless(1),但檢查它:man pager)。另一方面,即使對於一個守護進程,直接寫入STDOUT也不算犯罪,儘管不能保證有人會在那裏讀取輸出。

有關更好的解釋,請參閱Richard Stevens關於進程組,會話和控制終端的「Advanced Programming in the UNIX Environment」。

+0

真的非常感謝您的鏈接。神奇的書,我一直在尋找就像那樣=)關於我的問題:在我的情況下,殼是會議的領導者。當我運行我的編程時,shell會創建新的組並相應地設置控制終端,即我的編程控制終端。比它叉和死。分叉過程不會改變其組,因此它必須有控制終端,即使在父母死亡之後。因此它不能成爲守護進程。我不對? – DimG 2010-12-13 13:58:06

+0

嗯,我已經試過運行/ bin/ps -o pid,ppid,pgid,sid,tty,state,你的示例中的參數 - 是的,它保留了控制終端等。所以我的回答基本上是錯誤的。 – Dallaylaen 2010-12-13 15:34:00

+0

嘗試執行「/ usr/bin/strace」,-f,「/ usr/bin/man」...並使用2>文件運行該程序,您會看到(文件內)爲什麼尋呼機失敗。 – Dallaylaen 2010-12-13 16:40:54