2012-02-21 199 views
3
int main(){ 

    char ch; 

    fork(); 

    cin >> c; 
} 

調用fork()後,我應該有2個確切的進程運行相同的代碼。爲什麼在運行這個簡單的例子之後,我要麼只輸入一次字符,要麼輸入兩次?每次運行此程序時,系統是否都需要2次輸入?fork()發生了什麼?

>./a.out 
a 
>./a.out 
a 
b 
> 
+2

這不是C代碼,您使用的是C++運算符,因此我們這些不會說C++的人不能幫助您。 – tbert 2012-02-21 14:10:39

+0

第二個過程很有可能會得到在'a'後面輸入的\ n字符。嘗試將'ch'的類型改爲'std :: string',看看會發生什麼。 – dasblinkenlight 2012-02-21 14:12:06

+0

我剛剛做了,它的行爲方式也是一樣。 – 2012-02-21 14:14:09

回答

6

您有兩個進程在同一時間從終端讀取。有人猜測哪個進程得到了輸入。

  • 如果父進程首先獲取輸入,它將退出並將控制權返回給shell。 (請注意,這實際上會導致相同情況的重複,並且shell和子進程爭奪輸入。)
  • 如果子進程首先獲取輸入,則它會退出,但控制不會返回到shell直到父進程退出。

如果您有兩個進程從同一個終端讀取,您不應該期待一致的行爲。

+0

請注意,在第一種情況下,第二個進程遲早會得到一行輸入。在shell提示符後,也許;在這種情況下,它似乎會從shell中竊取一條線。 – 2012-02-21 14:42:39

+0

@James我懷疑它:父進程將關閉,即使它沒有收到它要求的輸入,孩子也會關閉。 – 2012-02-21 14:49:10

+1

@ Cookie503父進程無法關閉子進程中的打開fd。問題是這個fd點在哪裏。如果它指向一個物理終端(一個實際設備),該設備保持打開狀態。如果它指向邏輯終端(窗口,遠程登錄等),則邏輯設備保持打開狀態,但它指向的位置或對未來IO的反應如何可能改變,例如,會話組發生了變化。 – 2012-02-21 15:05:48

2

調用fork()時,操作系統通常複製正在執行的程序的整個內存空間(排序)。這兩個程序然後運行。唯一的區別是,在「新」進程中,fork()返回0,在「舊」進程中返回新進程的進程ID。

您只需要輸入一個輸入的原因是其中一個程序正在後臺運行。命令行shell一次只能執行一個進程的I/O。

1

fork()創建一個子進程。

但是哪一個進程(在父輩和新出生的孩子之間)得到CPU片是未確定的。當兩個進程都被阻止進行鍵盤輸入時,子進程或父進程可以獲得輸入。 如果父節點獲取該令牌,它會將輸入讀入其地址空間中定義的變量並退出。而孩子從來沒有機會從輸入中讀取。這個孤兒過程將被'根'過程採用(pid = 1)。見ps輸出。

而在另一種情況下,如果孩子獲取令牌並讀取數據並退出,則父級仍處於活動狀態,因此會再次阻止輸入。

+0

即使父母退出,孩子仍然應該是同一個終端組的一部分,不是嗎? (我不確定,自從我在這個層次上工作已經有一段時間了)。在這種情況下,遲早會得到一條線 - 它不再與已退出的父親競爭,而是與殼。 – 2012-02-21 14:44:44

0

在fork()後加入wait()並嘗試。