2011-06-18 28 views
2

我運行了幾個程序,使用fork(),接着是execve()來自第三個程序。所有這些程序都是要完成的,但最後第三個程序不會返回,即不顯示命令提示符。爲什麼程序的行爲取決於子程序的順序?

如果我在調用程序中使用wait()命令,那麼execve的程序只有在等待語句的順序與execve程序的結尾順序匹配時纔會返回。爲什麼會這樣?

這裏的簡化代碼:

int main() 
{ 
    int child1,child2,status; 
    char*newargv1[] = {./xyz",NULL}; 
    char *newargv2[] = {./abc",NULL}; 

    if((child1 = fork())==0) 
     execve(newargv1[0],newargv1,NULL); 
    if((child2 = fork())==0) 
     execve(newargv2[0],newargv2,NULL); 

    while(wait(&status) != child1); 
    while(wait(&status) != child2); 
    } 

它如果child1完成第一個工作正常。 ./xyz和./abc有一些簡單的處理和控制到最後。

+3

向我們展示代碼。 – cnicutar

+0

@cnicular添加了代碼 –

+0

使用waitpid與非阻塞標誌和輪詢,而不是等待。 – Keith

回答

6
while(wait(&status) != child1); 
while(wait(&status) != child2); 

在此代碼 - 你會等到child1完成,但如果第一child2完成 - 你會得到的地位和丟棄它。然後,當child1完成時 - 您將進入下一個循環,但您永遠不會獲得child2的狀態,因爲您已經丟棄它。

取而代之的是,保持一個子數組,並在wait上循環,直到在單個while循環中獲得陣列中每個成員的狀態爲止,那麼您將不會死鎖。

1

這聽起來像是你描述的正確行爲。 wait()阻塞,直到它正在等待的事情發生。如果程序wait對於連續幾件事情,它將不得不等待連續幾件事情。這聽起來像你使用waitpid()而不是wait()。如果您使用實際wait(),則只需將其稱爲與要等待的孩子相同的次數即可。

如果您不在乎訂單是什麼,請使程序不依賴於任何特定順序。

+0

不,我正在使用wait()。我的意思是,等待的順序必須與返回的順序相匹配,否則它不起作用。這樣一個實現的返回順序是無法控制的。 –

+2

我在說的是,這似乎是不必要的。除了此檢查之外,您似乎沒有將pid_t返回值用於導致問題的原因。所以**不要那樣做**。只需調用'wait'兩次並忽略返回值。 ...並擺脫循環!只要做:'(void)等待(&狀態); (無效)等待(狀態);' –

相關問題