2016-03-15 56 views
2

在研究CSAPP,我遇到的做法:列出所有可能的輸出序列進行下面的程序:c:函數waitpid如何工作?

int main() 
{ 
     if(Fork()==0) { 
       printf("a"); 
     } 
     else { 
       printf("b"); 
       waitpid(-1,NULL,0); 
     } 
     printf("c"); 
     exit(0); 
} 

的答案是:ACBC ABCC bcac BACC;

爲什麼bcac是正確的?函數waitpid()暫停執行調用進程,直到其等待集中的子進程終止。因此,家長不能打印c,直到子進程終止,這意味着孩子同時打印ac
我真的很困惑。我不知道爲什麼bcac是正確的。父進程應保持或暫停,直到孩子終止。

+5

你確定它的'Fork()'? –

+2

可能是由於緩衝。輸出到'stdout'(這是'printf'正在使用的)默認情況下是*行緩衝*。直到緩衝區已滿(不會在這裏發生),打印出一個換行符(這裏沒有發生),還有一個明確的'fflush'調用(這裏不會發生),或者進程退出並退出被刷新。 –

+0

可能是另一個複製到:http://stackoverflow.com/q/2530663/694576 – alk

回答

1

正如Joachim Pileborg所說,這是一個沖洗輸出問題。 只需使用以下命令:

int main() 
{ 
    if(Fork()==0) 
    { 
     printf("a\n"); 
    } 
    else 
    { 
     printf("b\n"); 
     waitpid(-1,NULL,0); 
    } 
    printf("c\n"); 
    exit(0); 
} 

'\ n' 字符應該自動刷新stdout或stderr。 你也可以使用fflush(stdout);

+1

我傾向於不同意,這不能成爲緩衝問題,因爲exit()會隱式地刷新標準輸出。 – Ctx

+0

@Ctx這是否完全確定只有在stdout被刷新後纔會喚醒父進程? – jdarthenay

+0

是的,在標準緩衝的情況下,您將獲得帶有OP代碼的'acbc'。假設沒有緩衝,另外'abcc'和'bacc'是可能的。 'bcac'永遠不會。 – Ctx