1 回答

TA貢獻(xiàn)1860條經(jīng)驗(yàn) 獲得超8個(gè)贊
我們將假設(shè)一個(gè)類 Unix 系統(tǒng),使用一個(gè)理解并參與作業(yè)控制的 shell (現(xiàn)在他們都這樣做了)。當(dāng)您運(yùn)行命令時(shí),shell 會(huì)創(chuàng)建一個(gè)稱為進(jìn)程組或“pgroup”的東西來(lái)保存構(gòu)成命令的每個(gè)進(jìn)程。如果命令是管道(就像這個(gè)一樣),管道中的每個(gè)進(jìn)程都會(huì)獲得相同的 pgroup-ID(請(qǐng)參閱 參考資料setpgid
)。
如果命令在前臺(tái)運(yùn)行(不帶&
),則控制終端會(huì)分配給它這個(gè)特定的 pgid。按下信號(hào)生成鍵之一,例如CTRL-C或CTRL-\,將相應(yīng)的信號(hào)(SIGINT
和SIGQUIT
在這些情況下)發(fā)送到 pgroup,使用內(nèi)部killpg
或等效。這會(huì)將信號(hào)發(fā)送給 pgroup 的每個(gè)成員。
(后臺(tái)進(jìn)程只是簡(jiǎn)單地*咳嗽*收回控制 tty 上的 pgid,然后重新啟動(dòng)管道中的進(jìn)程。但是,要做到這一點(diǎn)并不那么簡(jiǎn)單,正如這里的“重新啟動(dòng)”所示。)
這里問(wèn)題的可能來(lái)源是交互式程序會(huì)將控制終端置于cbreak或raw模式并禁用來(lái)自鍵盤鍵的部分或全部信號(hào),這樣,例如,CTRL-C不再導(dǎo)致內(nèi)核的 tty 模塊在全部。相反,如果您看到應(yīng)該導(dǎo)致暫停 ( CTRL-Z) 或終止的鍵,則程序必須執(zhí)行自己的暫?;蚪K止。程序員有時(shí)認(rèn)為這只是暫?;蚪K止——但由于整個(gè)管道從未收到有問(wèn)題的信號(hào),所以情況并非如此,除非整個(gè) shell 管道僅由交互式程序組成。
解決方法是讓程序在對(duì)控制終端進(jìn)行任何必要的清理(臨時(shí)或永久)之后將信號(hào)發(fā)送到它自己的 pgroup。
- 1 回答
- 0 關(guān)注
- 117 瀏覽
添加回答
舉報(bào)