以前我們在看《unix環境進階編程》的時候,有專門的整章詳細介紹如何編寫一個後台daemon程式(精靈程式),主要涉及到建立交談群組,切換工作目錄,設定檔案檢測字,關閉不必要的描述符等多個操作。這些操作對於每一個背景程式來說都是類似的。
在Linux中專門提供了一個函數來完成這個daemon化的過程,這個函數的原型如下
int daemon (int __nochdir, int __noclose);
如果__nochdir的值為0,則將切換工作目錄為根目錄;如果__noclose為0,則將標準輸入,輸出和標準錯誤都重新導向到/dev/null。
經過這個函數調用後的程式將運行在後台,成為一個daemon程式,而linux下大多的服務都是以此方式啟動並執行。
我們來看一個簡單的例子。例如編寫例子程式test.c
#include <unistd.h>#include <stdio.h> int do_sth(){ //Add what u want
printf("hello/n"); return 0;}int main(){ daemon(0,0); while ( 1 ) { do_sth(); sleep(1); }}
編譯並運行:
whc@ubuntu:~/test$ gcc -Wall test.c -o www
whc@ubuntu:~/test$ ./www
程式進入後台,通過ps查看進程情況,可以看到進程的父進程的id為1,即為init進程
whc@ubuntu:~/test$ ps -elf | grep www
5 S www-data 20173 6295 0 80 0 - 6038 - 05:04 ? 00:00:00 /usr/sbin/apache2 -k start
1 S whc 26721 1 0 80 0 - 390 - 10:14 ? 00:00:00 ./www
0 R whc 26752 26657 0 80 0 - 805 - 10:15 pts/4 00:00:00 grep www
用lsof查看www進程所開啟的檔案,可以看到檔案描述符0,1,2都被重新導向到/dev/null
whc@ubuntu:~/test$ /usr/bin/lsof -p 26721
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
www 26721 whc cwd DIR 8,1 4096 2 /
www 26721 whc rtd DIR 8,1 4096 2 /
www 26721 whc txt REG 8,3 6491 101021 /home/whc/weihua_work/守護進程/www
www 26721 whc mem REG 8,1 1364388 458293 /lib/tls/i686/cmov/libc-2.7.so
www 26721 whc mem REG 8,1 109152 432499 /lib/ld-2.7.so
www 26721 whc 0u CHR 1,3 6448 /dev/null
www 26721 whc 1u CHR 1,3 6448 /dev/null
www 26721 whc 2u CHR 1,3 6448 /dev/null
並且能後看到,進程的當前工作目錄(cwd)為根目錄 '/',daemon函數已經協助我們完成了daemon化的過程接下來我們只需關注程式功能的實現就可以了