標籤:com dev 改變 img 作用 很多 設定 錯誤輸出 最大
守護進程最大的特點就是不受終端控制,並且在後台運行。linux上很多應用都是以守護進程的方式存在的,比如常用的crond。把應用做成守護進程的好處就是可以脫離終端,不會因為終端的關閉而掛掉,會隨著系統的存在而存在。
建立守護進程有以下幾個要點:
<1> 建立子進程,殺掉父進程。
這麼做主要是為了確保進行操作<2>的進程不是交談群組長,因為交談群組組長調用setsid會失敗。
<2> 調用setsid()
每個進程都屬於一個進程組,進程組號就是進程組組長的pid。多個進程組屬於一個會話(一次登入形成一個會話),會話獨享一個終端。setsid的作用是使調用進程成為新的交談群組長和新的進程組組長。這麼幹是因為現在的進程是fork出來的,那麼就繼承了父進程的會話和進程組。如果會話關閉,很有可能會給進程組中的每一個進程都發送一個SIGHUP訊號來停止進程。所以我們通過setsid來脫離父進程原來的會話和進程組。
<3> 禁止進程重新開啟終端
第<2>步之後,進程成為了交談群組長,可以申請重新開啟一個終端。第<2>步中強調了終端對進程的影響,所以我們應該禁止該進程重新擷取一個終端,一般是通過fork,關閉父進程,繼續使用子進程,使該進程不再是交談群組長。
<4> 關閉檔案描述符
進程fork的時候,子進程會拷貝父進程的檔案描述符,子進程一般不使用它們。但是如果檔案描述符保持開啟狀態,那麼會造成檔案系統無法卸下以及一些無法預料的錯誤。所以我們應該關閉從父進程拷貝到的檔案描述符。除了一般的檔案描述符,守護進程一般是不與終端互動的,所以STDIN, STDERR, STDOUT都應該被重新導向到/dev/null。一般使用dup和dup2來完成。但是如果希望得到守護進程的輸出,或者錯誤輸出,則可以使用dup或者dup2將STDERR和STDOUT重新導向到特殊的檔案。
<5> 切換當前的工作目錄
由於進程活動的目錄不能被檔案系統卸下,但是守護進程一般開啟就不會再關閉了,所以它會一直佔用著這個目錄不讓檔案系統卸下。所以一般會把守護進程的工作目錄切換到永遠也不會被檔案系統卸下的根目錄。
<6> 改變檔案掩碼
在fork時,子進程不光拷貝了父進程的檔案描述符,而且連檔案掩碼也一塊拷貝過來了。如果父進程使用umask設定了一些特殊的許可權,那麼子進程在建立檔案時很可能就會因為設定許可權時被拒絕而失敗。所以應該使用umask(0)來重設檔案掩碼。
實現如下:
代碼運行結束後,daemon_out.txt 和 daemon_err.txt中有了對應的字串輸出。
C語言建立守護進程