2017-04-25 84 views
1

我有這樣的C代碼fork爲這個c程序產生不正確的輸出?

/* SIGCHLD handler. */ 
static void sigchld_hdl (int sig) 
{ 
    /* Wait for all dead processes. 
    * We use a non-blocking call to be sure this signal handler will not 
    * block if a child was cleaned up in another part of the program. */ 
    //printf("Inside handler: \n"); 
    while (waitpid(-1, NULL, WNOHANG) > 0) { 
     printf("reaped\n"); 
    } 
    //printf("Outside handler: \n"); 

} 

int main (int argc, char *argv[]) 
{ 
    struct sigaction act; 
    int i; 

    memset (&act, 0, sizeof(act)); 
    act.sa_handler = sigchld_hdl; 

    if (sigaction(SIGCHLD, &act, 0)) { 
     perror ("sigaction"); 
     return 1; 
    } 

    /* Make some children. */ 
    for (i = 0; i < 5; i++) { 
     switch (fork()) { 
      case -1: 
       perror ("fork"); 
       return 1; 
      case 0: 
       exit(0); 
       return 0; 
      default: 
       //printf("inside parent\n"); 
       printf("Created child %d\n", i); 

     } 
    } 

    /* Wait until we get a sleep() call that is not interrupted by a signal. */ 
    while (sleep(1)) { 
     printf("inside parent while loop\n"); 
    } 

    return 0; 
} 

我打電話叉5次,所以我預計共有5子進程和1個父進程。當我運行這個代碼,我得到這個輸出

Created child 0 
Created child 1 
reaped 
reaped 
Created child 2 
Created child 3 
Created child 3 
reaped 
reaped 
Created child 4 
reaped 
inside parent while loop 

我不能完全弄清楚爲什麼我看到child3兩次。關於我,不應該有任何重複,因爲我在每一次迭代中都在增加。

有人可以解釋爲什麼我看到child3兩次?

+1

我無法複製它。你不應該在信號處理程序中調用'printf()',也許這就是問題所在。 – Barmar

+0

@Barmar爲什麼我不應該在處理程序中調用printf。你必須運行幾次才能重現。 – Dude

+1

它不是異步安全的。 http://stackoverflow.com/questions/16891019/how-to-avoid-using-printf-in-a-signal-handler – Barmar

回答

0

問題是您的調試輸出。在你的異步信號處理程序中調用printf是未定義的行爲。在信號處理程序中只有一小段保證安全的功能。

如果您刪除它,您會看到信號處理程序之外的一個從未出現意外的行爲。

+0

我得到意外的行爲爲主,而不是處理程序中的代碼。創建的子進程來自父進程x。 – Dude

+0

症狀出現在哪裏並不重要。 – covener

1

stdio緩衝區的狀態包含在進程的內存空間中。如果分叉時緩衝區不爲空,則父級和子級都有一個信息副本,其中"Child process 3\n"位於stdout緩衝區中,正在等待刷新。

他們最終都會沖洗它。

您可以通過在子進程中調用_exit而不是exit來避免此問題。 exit通常是一個糟糕的主意,當你在一個自成立以來尚未完成成功執行的進程中時。