linux平常學習:守護進程,會話與任務

關於session和shell:
常見的session通常是shell session,在終端中只有一個session,當咱們打開一個新的終端時,總會建立一個新session,session由一個或多個進程組組成,通常狀況下shell進程看成session的領頭進程。領頭進程的PID看成seeesion的SID。session中的每一個進程組被稱爲一個job。html

關於job(任務):
執行一個命令會建立一個或多個進程,這些進程共屬於一個進程組,每一個進程組有一個group leader,group leader的pid就是進程組的id,經過ps命令能夠查看進程的進程組id:ps -o pgid。
經過管道鏈接的進程屬於相同的進程組,子進程會繼承父進程的進程組和SID。(咱們知道命令進程都是經過shell進程fork生成子進程執行的,那麼一個session中是否是隻有一個進程組呢?)
(答案:由shell進程fork出的子進程原本具備和shell相同的session、進程組和控制終端,可是shell調用setpgid函數將做業中的某個子進程指定爲一個新進程組的group leader,而後調用setpgid將該做業中的其它子進程也轉移到這個進程組中。若是這個進程組須要在前臺運行,就調用 tcsetpgrp函數將它設置爲前臺進程組,因爲一個session只能有一個前臺進程組,因此shell所在的進程組就自動變成後臺進程組。)
一個session同時只能有一個前臺job,其他的都是後臺job,每一個session鏈接一個控制終端(control terminal)。控制終端的輸入會被髮送給前臺job,前臺job的標準輸出也會發送給控制終端,同時由控制終端產生的信號也會傳遞給前臺job。
將進程放入不一樣的session的惟一方法是:setsid使其成爲新session的領頭進程,同時本進程會被放入一個新的進程組中。shell

關於control terminal(控制終端):
控制終端是進程的一個屬性,子進程會從父進程繼承控制終端,因此一個session中的全部進程都會從領頭進程處繼承控制終端屬性。服務器

將多個進程放到一個進程組的主要目的是便於管理,能夠向同一個進程組發送信號。
關於kill:
kill命令默認向進程發送SIGTERM信號,可是SIGTERM信號能夠被進程設置爲忽略,所以沒法關閉這些進程。這時候使用kill -SIGKILL (kill -9) PID發送SIGKILL命令,這個信號是不能被忽略的。網絡

關於session消亡:
當session中全部的進程都退出時session就消亡了,正常的消亡過程:內核發現終端關閉,發送SIGHUP信號給session領頭進程,session領頭進程接收SIGHUP信號,並將該信號發送給session中的每個進程,SIGHUP信號的默認處理方法是結束進程。
內核發現終端關閉:多是遠程登錄時網絡斷開,或者手動x掉了終端窗口。session

關於守護進程:
守護進程是一種獨立於控制終端的後臺進程,沒法經過控制終端和用戶進行交互,守護進程是一種長時間執行的進程,好比說服務器程序。經過調用setsid函數讓一個進程成爲守護進程(建立新session,放棄終端,建立新進程組)。函數

關於setsid函數:
調用setstd函數會建立一個新的session,而且該進程成爲session的領頭進程,並且該進程會以本身的PID建立一個新的進程組。調用這個函數的進程不容許是某一個session的領頭進程。(經過fork避免這個問題)setsid會放棄當前的控制終端。spa

ps -x參數能夠顯示全部與終端無關的進程
-a 顯示全部與終端相關的進程
-u 以用戶爲中心組織進程信息顯示.net

參考文章:
https://my.oschina.net/moooof...
https://www.cnblogs.com/spark...
https://www.jb51.net/article/...htm

相關文章
相關標籤/搜索