2011-11-09 46 views
1

我有一個Linux進程(我們稱之爲主進程),它的標準輸出通過shell的管道運算符管道到另一進程(稱爲下游進程) (|)。如果下游進程崩潰,則主進程設置爲接收SIGPIPE信號。不幸的是,直到主進程寫入標準輸出爲止,SIGPIPE纔會被引發。有沒有辦法可以更快地告訴下游流程已經終止?如何判斷Unix管道中的下游進程是否已經崩潰

一種方法是連續寫入下游過程,但這看起來很浪費。另一種方法是有一個單獨的監督程序進程來監視所有相關的進程,但這很複雜。或者也許有一些方法可以使用select()來觸發信號。我希望主流程能夠自己做到這一切。

+0

是否有必要立即知道下游進程崩潰的時間,還是隻有在下一次有東西寫入時才知道崩潰了就足夠了? – zwol

+0

正如我在問題中提到的那樣,我想知道下游進程會更快崩潰,而不是下一次寫入(可能會在我的上下文中處於不確定的時間)。 –

回答

3

它出現在標準輸出文件描述符變得 「讀就緒」,當接收器崩潰:

$ gcc -Wall select-downstream-crash.c -o select-downstream-crash 
$ gcc -Wall crash-in-five-seconds.c -o crash-in-five-seconds 
$ ./select-downstream-crash | ./crash-in-five-seconds 
    ... five seconds pass ... 
stdout is ready for reading 
Segmentation fault 

選擇-下游crash.c

#include <err.h> 
#include <stdio.h> 
#include <sys/select.h> 
#include <unistd.h> 

int main(void) 
{ 
    fd_set readfds; 
    int rc; 

    FD_ZERO(&readfds); 
    FD_SET(STDOUT_FILENO, &readfds); 

    rc = select(STDOUT_FILENO + 1, &readfds, NULL, NULL, NULL); 
    if (rc < 0) 
     err(1, "select"); 

    if (FD_ISSET(STDOUT_FILENO, &readfds)) 
     fprintf(stderr, "stdout is ready for reading\n"); 

    return 0; 
} 

碰撞在五-seconds.c

#include <stdio.h> 
#include <unistd.h> 

int main(void) 
{ 
    sleep(5); 
    putchar(*(char*)NULL); 
    return 0; 
} 

我在Linux上試過,但不知道它是否可以在其他地方使用。找到解釋這一觀察結果的文檔是很好的。

0

如果主進程fork是其他進程,那麼它會在退出時得到SIGCHLD通知。

+0

沒錯。不幸的是,下游過程由外殼創建並通過管道操作員連接:'main | downstream'。 –

相關問題