Daemon 進程生命周期長且在后臺運行。編寫daemon進程需要遵循哪些規則呢?
1、執行fork()函數,父進程退出,子進程繼續
執行這一步,原因有兩個:
父進程可能是進程組的組長,從而不能夠執行后面要執行的setsid函數。
子進程繼承了父進程的進程組ID,一定不會是進程組組長,所以子進程一定可以執行setsid。
如果daemon是從終端命令行啟動的,那么父進程退出后,shell會顯示shell提示符,讓子進程在后臺執行。
2、子進程執行下面三個步驟
修改當前目錄為根目錄 如果當前工作路徑上包含根文件系統以外的文件系統,那么這個文件系統將不能被卸載。
當然也可以改成其它合適的目錄。這里使用函數chdir("/")。
調用setsid 這是為了切斷與控制終端的所有關系,創建一個新的會話。
此時無論終端是否發送SIGIN、SIGQUIT或者SIGTSTP或者斷開,都與daemon進程無關。
使用umask(0)設置文件模式創建掩碼為0 這一步的目的是讓daemon進程創建文件的權限屬性與shell脫離關系。
因為默認情況下,進程的umask來源于父進程shell的umask。如果不執行umask(0),那么父進程的shell就會影響daemon,造成daemon每次執行的umask信息不一致。
3、再次執行fork,父進程退出,子進程繼續
執行完前面兩步之后,新建了會話,進程是會話的首進程,也是進程組的首進程;進程ID,進程組ID,會話ID相同;進程和終端失去聯系。
但是還差一步。daemon進程有可能會打開一個終端設備:
intfd=open("/dev/console",O_RDWR);這個設備是否會成為daemon進程的控制終端,取決于兩點:
daemon進程是不是會話的首進程。
系統實現。(BSD的實現不會成為daemon的控制終端,但POSIX由具體實現決定)。
為了萬無一失,需要使用fork()確保daemon不是會話的首進程。
4、關閉stdin,stdout,stderr
關閉之后應該打開/dev/null將0,1,2描述符指向它。這是為了防止后面執行0,1,2上的I/O時出現錯誤。
C庫的daemon函數和這個流程相似,但沒有第二次fork。
原文標題:Daemon 進程的創建
文章出處:【微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。
責任編輯:haq
-
編程
+關注
關注
88文章
3627瀏覽量
93809 -
函數
+關注
關注
3文章
4338瀏覽量
62739
原文標題:Daemon 進程的創建
文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論