1. 程式人生 > >Linux下的守護程序與建立方法

Linux下的守護程序與建立方法

1、我們先來了解一下什麼是守護程序?
守護程序也稱精靈程序(Daemon),是執行在後臺的一種特殊程序。它獨立於控制終端並且週期性地執行某種任務或等待處理某些發生的事件。守護程序是生存期長的一種程序。它們常常在系統引導裝入時啟動,僅在系統關閉時才終止。因為它們沒有控制終端,所以說它們是在後臺執行的。

2、守護程序的特點:
(1)Linux系統啟動時會啟動很多系統服務程序,守護程序沒有控制終端,不能直接和使用者互動
(2)其他程序都是在使用者登入或執行程式時建立,在執行結束或使用者登出時終止,但守護程序不受使用者登入登出的影響,只受開機或者關機的影響。

3、守護程序存在的原因:
daemon函式存在的原因是因為控制終端由於某些原因(如斷開終端連結)會發送一些訊號的原因。而接收處理這些訊號的預設動作會讓程序退出。這些訊號會由於終端上敲一些特殊按鍵而產生。

4、守護程序和後臺程序的區別:
(1)守護程序是後臺程序,後臺程序不一定是守護程序
(2)守護程序執行是與終端無關的,是不能往終端上打訊息的
(3)守護程序的會話組和當前目錄,檔案描述符都是獨立的。後臺執行只是終端進行了一次fork,讓程式在後臺執行

5、建立守護程序方法:

建立守護程序最關鍵的一步是呼叫setsid函式建立一個新的會話(Session),併成為Session Leader。

#include<unistd.h>
pid_t setsid(void);

該函式呼叫成功時返回新建立的Session的id(其實也就是當前程序的id),出錯返回-1。注意,呼叫這個函式之前,當前程序不允許是程序組的Leader,否則該函式返回-1。要保證當前程序不是程序組的Leader也很容易,只要先fork再呼叫setsid就行了。fork建立的子程序和父程序在同一個程序組中,程序組的Leader必然是該組的第一個程序,所以子程序不可能是該組的第一個程序,在子程序中呼叫setsid就不會有問題了。

成功呼叫該函式的結果是:
(1)建立一個新的Session,當前程序成為Session Leader,當前程序的id就是Session的id。
(2)建立一個新的程序組,當前程序成為程序組的Leader,當前程序的id就是程序組的id。
(3)如果當前程序原本有一個控制終端,則它失去這個控制終端,成為一個沒有控制終端的程序。所謂失去控制終端是指,原來的控制終端仍然是開啟的,仍然可以讀寫,但只是一個普通的開啟檔案而不是控制終端了。

6、建立守護程序的步驟:
(1)呼叫umask將檔案模式建立遮蔽字設定為0
(2)父程序fork出子程序,然後子程序呼叫setsid,父程序直接退出(保證了子程序不是一個程序組的組長),
(3)呼叫setsid建立一個新的會話(呼叫成功會使呼叫程序成為新會話的首程序,並且成為一個程序組的組長程序,呼叫程序沒有控制終端)
(4)將當前工作目錄更改為根目錄
(5)關閉不在需要的檔案描述符
(6)忽略SIGCHLD訊號
無程式碼無真相,

#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/stat.h>
void mydaemon()
{
    int i,fd0;
    pid_t pid;
    struct sigaction sa;
    umask(0);
    if(pid=fork()>0)  //建立子程序,讓父程序退出
        return;
    setsid();         //建立會話
    sa.sa_flags=0;
    if(sigaction(SIGCHLD,&sa,NULL<0))
        return;
    if(pid=fork()>0)        //第二次fork
        return;
    if(chdir("/")<0)
        return ;
    close(0);
    fd0=open("/dev/null",O_RDWR);
    dup2(fd0,1);
    dup2(fd0,2);
}
int main()
{
   mydaemon();

   while(1)
       sleep(1);
   return 0;
}

說明:第二次fork()是為了防止後期操作失誤而開啟守護程序的終端。
這裡寫圖片描述
既然守護程序在後臺執行,那麼如何刪除一個創建出來的守護程序呢?
可以給程序發9號訊號:kill -9 pid,這樣就可以了。