Unix环境高级编程—进程关系
終端登錄
網絡登錄
進程組
getpgrp(void)
setpgid(pid_t?pid,?pid_)
?
會話:?是一個或多個進程組的集合,通常由shell的管道將幾個進程編成一組。
setsid(void)
getsid(pid_t?pid)
?
會話建立過程,簡述:
???? 其中,xinetd守護進程在監聽到有客戶端請求ssh連接后,fork一個子進程xinetd,然后該子進程exec執行sshd程序(也就圖中的PPID為3944),而父進程xinetd則繼續監聽網絡中其他連接請求的到來。
???sshd程序調用login程序,拋出一個登錄shell(圖中PID為11081),此時該進程權限為root權限,同時,打開文件描述符0,1,2,方便用戶進行輸入用戶名密碼這兩個簡單的交互,如果用戶名密碼準確無誤,則fork一個新的進程作為控制終端(pts/0,該進程ID為11085),并降低權限,由root權限更改為登錄用戶名對應的權限。最后,由控制終端fork一個控制進程,來作為與控制終端連接的會話首進程,也就是圖中的PID為11086的進程,至此,一個完整的會話建立完畢,我們在這個偽終端中執行的任何命令的進程的PPID都應該為11086(如圖中ps?-ef?,grep?webber的父進程都是11086),因為它們都是在這個會話中完成的,而這個會話首進程的進程組ID為11086.
?
注:一個會話只能有一個前臺進程組,其他進程組為后臺進程組。在終端鍵入中斷鍵(Ctrl+C),都會將信號送到前臺進程組fg,如果將掛斷信號發送到控制進程(會話首進程11086),則pts斷開連接。
保證程序能與控制終端對話的方法是open文件?/dev/tty或?/dev/pts/0?
?
作業控制:
終端IO和終端產生的信號總是從前臺進程組連接到實際終端。
后臺進程的輸出是否出現在終端是可選擇的,如果選擇讓后臺進程輸出不出現在終端(用 stty 命令),則SIGTTOU會將該進程在后臺阻塞。
?
對于前臺、后臺作業以及終端驅動程序的作業控制功能如下圖:
?
Shell執行程序
?
使用的登錄shell不同,則創建各個進程的順序也可能不同。
?
ps?-o?pid,ppid,pgid,tpgid,sid,comm|cat?|cat
對于這條命令,在shell環境下,首先創建執行管道中最后一個cat的進程,然后它fork兩個進程,分別是倒數第二個cat和第一個ps,然后它們分別執行exec,通過管道完成任務(這里可能產生競爭條件),最終輸出到終端。而在Bash環境下,Bash將是管道中三個命令的父進程,bash是后臺進程,而那三個命令是前臺進程。
?
孤兒進程組:
????? 這里所說的孤兒進程組其實很好理解,我們可以舉一個最簡單的例子,在我們通過pts創建一個會話時,在/bin/bash的登錄環境下,系統會指定一個會話首進程來作為其他命令進程的父進程,這個會話首進程會做為后臺進程組的組長(假設PID=1000),這時,我們可以執行一段代碼在前臺執行(假設執行程序的進程的PID=2000),在這段代碼中fork了一個子進程(假設PID=3000),那么PID為2000和3000的父子進程組成了一個前臺進程組,其中,父進程PID=2000的作為前臺進程組的組長。那么,當我們先把PID=3000的子進程掛起停止運行后,再殺死PID=2000的父進程或者父進程主動exit,這時,這個只有PID=3000的子進程的前臺進程組成為孤兒進程組,被init收養,同時,這個前臺進程組變為后臺進程組,而會話首進程PID=1000的進程組成為前臺進程組。這時內核可以向孤兒進程組發送SIGCONT信號,使孤兒進程組繼續執行。
???注意,對于孤兒進程組,如果內核用SIGTTIN信號去停止它,則此進程組就再也不會繼續執行,不在接受SIGCONT信號。POSIX.1要求向新孤兒進程組中處于停止狀態的每一個進程發送掛掉信號(SIGHUP),接著向其發送繼續信號(SIGCONT)。
???????????? ? ?
轉載于:https://www.cnblogs.com/webber1992/p/5850754.html
總結
以上是生活随笔為你收集整理的Unix环境高级编程—进程关系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Singleton Pattern (单
- 下一篇: Linux程序包管理(yum)