ubuntu下使用C/C++開發設計自己的Daemon(service)服務(LINUX上的背景服務)
ubuntu下使用C/C++開發設計自己的Daemon(service)服務(LINUX上的背景服務)
GITHUB : https://github.com/jash-git/Jash_QT/tree/master/056_Qt_service (PS自己在Linux C_Qt 備份中有在『056_Qt_service』、『cpp_service』實作成功)
不知如何開機自動啟動,在看到debian系統的初始化後茅塞頓開,網上介紹Daemon的文章多如牛毛,青年人網就不介紹了, Daemon在各個Unix平臺下的原理是一樣的,只是實現細節上的不同罷了,現在寫了一個精簡的Daemon,詳細的可以參照《Unix環境高級程式設計》
以ubuntu為例(ubuntu為debian的分支,所以系統程式設計和配置極為相似),
代碼如下
//mydaemon.c #include<unistd.h> #include<stdlib.h> #include<sys/param.h> #include<sys/types.h> #include<sys/stat.h> void init_daemon(void) { int pid; int i; if(pid=fork()) exit(0); else if(pid<0) exit(1); //是第一子進程 setsid();//第一子進程成為新的會話組長和進程組長, 並與控制終端分離 if(pid=fork()) exit(0);//結束第一子進程 else if(pid< 0) exit(1); //第二子進程不再是會話組長 for(i=0;i< NOFILE;++i)//關閉打開的文件描述符 close(i); chdir("/");//改變工作目錄到/ umask(0);//重設文件創建掩模 return; } int main() { init_daemon();//使進程成為Daemon //以下可以添加功能代碼 while(1) { sleep(10);//睡眠一分鐘 } return 0; }
編譯&執行命令
gcc mydaemon.c -o mydaemon ./mydaemon
如果成功,可以用ps -efjc查看,我們會發現這個進程的父進程為init,到這裡守護進程成功運行,許多Daemon如ftpd, httpd都設為開機自動運行,下面討論如何通過添加腳本讓系統來啟動Daemon,根據系統初始化原理一文(本blog已轉載)介紹,我/etc/init.d/中添加一個新建一個腳本,為mydaemon, 腳本如下,假設我的daemon目錄為/home/eyesmart/Daemon
#! /bin/sh # /etc/init.d/mydaemon: start the my daemon. PATH=/bin:/usr/bin:/sbin:/usr/sbin binpath=/home/eyesmart/Daemon/mydaemon test -f $binpath || exit 0 . /lib/lsb/init-functions case "$1" in start) log_begin_msg "Starting mydaemon..." start-stop-daemon --start --quiet--exec $binpath log_end_msg $? ;; stop) log_begin_msg "Stopping mydaemon..." start-stop-daemon --stop --retry TERM/1/TERM/1/TERM/4/KILL --quiet --oknodo--exec $binpath log_end_msg $? ;; restart|force-reload) $0 stop sleep 1 $0 start ;; *) log_success_msg "Usage: $binpath {start|stop|restart|force-reload}" exit 1 esac exit 0
大致是這樣,腳本可以按需要寫的再細緻些,做到這裡按說已經完成,但是unix有個run level這個特徵,所以我們必須對於特定的run level創建一個連結,一般linux是運行level 2,那麼我們輸入下列命令:
ln -s /etc/init.d/mydaemon /etc/rc2.d/S50mydaemon.
到這裡大功告成,當你重啟系統的時候你可以在開機過程中看到自己些的程式所顯示的資訊。
其他Unix系統環境在細節上會有所不同,但原理一樣。