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