作業、進程組、會話和守護進程

1. 進程組

每個進程除了有一個進程ID之外,還屬於一個進程組。進程組是一個或多個進程的集合。通常,它們與同一作業相關聯,可以接收來自同一終端的各種信號。每個進程組有一個唯一的進程組ID。每個進程組都可以有一個組長進程。組長進程的標識是,其進程組ID等於其進程ID。組長進程可以創建一個進組,創建該組中的進程,然後終止。只要在某個進程組中一個進程存在,則該進程組就存在,這與其組長進程是否終止無關。

wKioL1edn0by5SsYAAA5aAvLmr8197.png-wh_50

2.作業

Shell分前後臺來控制的不是進程而是作業(Job)或者進程組(Process Group)。一個前臺作業可以由多個進程組成,一個後臺也可以由多個進程組成,Shell可以運行一個前臺作業和任意多個後臺作業,這稱爲作業控制。

作業與進程組的區別:如果作業中的某個進程又創建了子進程,則子進程不屬於作業。一旦作業運行結束,Shell就把自己提到前臺,如果原來的前臺進程還存在(如果這個子進程還沒終止),它自動變爲後臺進程組。

前臺作業:可以由用戶參與交互及控制的作業我們稱之爲前臺作業。

後臺作業:在內存可以自運行的作業,用戶無法參與交互以及使用[ctrl]+c來終止,只能通過bg或fg來調用該作業。

3.會話

會話(Session)是一個或多個進程組的集合。一個會話可以有一個控制終端。這通常是登陸到其上的終端設備(在終端登陸情況下)或僞終端設備(在網絡登陸情況下)。建立與控制終端連接的會話首進程被稱爲控制進程。一個會話中的幾個進程組可被分爲一個前臺進程組以及一個或多個後臺進程組。所以一個會話中,應該包括控制進程(會話首進程),一個前臺進程組和任意後臺進程組。

4.控制終端

 一個會話只有一個控制終端,控制終端和會話中進程組的領頭進程相連。

5.守護進程

。daemon函數存在的原因是因爲控制終端由於某些原因(如斷開終端鏈接)會發送一些信號的原因。而接收進城處理這些信號缺省動作會讓進程退出。這些信號會由於終端上敲一些特殊按鍵而產生。

守護進程(Daemon)是運行在後臺的一種特殊進程。它獨立於控制終端並且週期性地執行某種任務或等待處理某些發生的事件。守護進程是一種很有用的進程。Linux的大多數服務器就是用守護進程實現的。

wKioL1edrJzS8e0lAABK8Eq-iLY652.png-wh_50

TPGID爲-1,表示與終端無關,TTY爲?

創建守護進程

1. 調用umask將文件模式創建屏蔽字設置爲0.

2. 調用fork,父進程退出(exit)。原因:1)如果該守護進程是作爲一條簡單的shell命令啓動的,那麼父進程終止使得shell認爲該命令已經執行完畢。2)保證子進程不是一個進程組的組長進程。

3. 調用setsid創建一個新會話。setsid會導致:1)調用進程成爲新會話的首進程。 2)調用進程成爲一個進程組的組長進程 。3)調用進程沒有控制終端。(再次fork一次,保證daemon進程,之後不會打開tty設備)

4. 將當前工作目錄更改爲根目錄。

5. 關閉不在需要的文件描述符。

6. 其他:忽略SIGCHLD信號。

注:有的也fork兩次

 1 、第一次fork的作用是讓shell 認爲本條命令 已經終止,不用掛在終端輸入上。還有一個作用是爲後面setsid服務。setsid的調用者不能是進程組組長(group leader). 此時父進程是進程組組長。    

    2 、setsid() 是本函數最重要的一個調用。它完成了daemon函數想要做的大部分事情。調用完整個函數。子進程是會話組長(sid==pid),也是進程組組長(pgid == pid),並且脫離了原來控制終端。到了這一步,基本上不管控制終端如何怎麼樣。新的進程都不會收到那些信號。

    3  、經過前面2個步驟,基本想要做的都做了。第2次fork不是必須的。fork第二次主要目的是。防止進程再次打開一個控制終端。因爲打開一個控制終端的前臺條件是該進程必須是會話組長。再fork一次,子進程ID != sid(sid是進程父進程的sid)。所以也無法打開新的控制終端。


wKioL1edr2HyOcN9AAB_G6iitlU980.png-wh_50

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章