2013-12-15 70 views
2

當我在閱讀APUE v3時,更具體地說,我發現自己無法掌握一些東西。 首先,讓我們asume我運行在UNIX外殼下面管道項目:作業感知shell vs作業不知道shell執行的程序

cat /etc/passwd | grep -i alex | awk -F : '{print $3}' | less 

在第一個例子,讓我們假設,我使用的是工作不瞭解殼(SH)

書解釋的是,在這種情況下,最終的PS -o PID,PPID,PGID,COM​​M將如下所示(假設殼的PID爲10,它的PPID是5)

PID  PPID  PGID  COMM 
10  5  10  sh 
11  10  10  less 
12  11  10  cat /etc/passwd 
13  11  10  grep -i alex 
14  11  10  awk -F : '{print $3}' 

在第二個例子讓我們假設我們正在使用作業感知shell(bash):

PID  PPID  PGID  COMM 
10  5  10  bash 
11  10  11  cat /etc/passwd 
12  10  11  grep -i alex 
13  10  11  awk -F : '{print $3}' 
14  10  11  less 

的問題是,爲何在第二種情況下,該方法是在外殼的孩子,而不是最後的處理(如在第一種情況),並且假定該外殼接收SIGCHLD爲每個它的孩子,是不是在孩子之間出現某種競爭狀態?

PS。對不起,錯誤的縮進。我會嘗試,現在解決這個問題 謝謝, 亞歷克斯

+0

想在這裏抓住你的問題......你的意思的時候,孩子死亡給他們的時間順序不會死的可能性之間的競爭條件?這兩個命令在任何情況下都會被處理(通過shell),所以AFAIK不會造成問題... – bryn

回答

1

的問題是,爲什麼在第二種情況下,該過程是外殼的孩子,而不是最後一個進程[...]

因爲這是正確的行爲。 shell中只有一個錯誤可以解釋爲什麼less將成爲管道中其他進程的父代。 less無法處理其他進程的SIGCHLD,因爲它尚未啓動它們。 (更重要的是,這也將導致問題由於less系統調用與EINTR錯誤失敗。)這也意味着,除了less所有的進程將通過PID 1,而不是shell來收割,因爲這樣會得到他們的SIGCHLD

否則,該進程的父子關係沒有什麼做的「工作意識到殼」。工作意識到殼做兩件事情:它實現了作業控制(jobsfgbg命令),並將其本身設置爲會議領導(使用setsid()系統調用),這樣SIGHUP會被自動發送到所有子進程時,它(殼)終止。

並假設shell爲它的每個孩子接收到一個SIGCHLD,這些孩子之間不會出現某種競爭條件?

競態條件是指事情未按預期順序執行的情況。這裏沒有預期的訂單。大多數過濾器應用程序(像grep這樣的過濾器:從標準輸入讀取,寫入標準輸出)只要他們在標準輸入上看到EOF就會終止。通常情況下,管道中的第一個進程可能已經在上一個進程已經看到任何輸入時終止。這很正常。他們獲得了收益,但是他們的產出已經被送往管道,並且會被正常處理。