守護進程詳細解讀

守護進程概念

守護進程也稱精靈進程,是運行在後臺的一種特殊進程。他獨立於終端而且週期性執行某種任務或者等待某件事情的發生。守護進程是一種頗有用的進程。好比不少的服務器都是以次方是運行在後臺,等待客戶端鏈接並處理相關問題的。服務器

系統中守護進程一般以d結尾標識。函數

建立守護進程關鍵的一步是調用setsid函數建立一個新的會話,並使之稱爲控制進程。spa

注:調用setsid建立守護進程的當前進程不得是進程組的leader,不然返回-1;保證這個條件的方式是:咱們在當前進程進行fork生成子進程,父進程直接退出,子進程調用setsid就能夠了。code

成功調用setsid函數的結果是:

1。建立一個新的會話,而且當前進程稱爲leader,當前進程id爲會話idblog

2。建立一個新的進程組,當前進程是進程組的leader,當前進程id就是進程組id進程

3。若是當前進程本來有一個控制終端,那麼他失去這個終端稱爲一個沒有終端控制的進程。it

建立守護進程

1調用umask將文件屏蔽字設置爲0io

2調用fork,父進程退出class

3調用setsid建立會話:結果1調用進程成爲會話首進程,2調用進程成爲進程組組長,3調用進程沒有控制終端後臺

4將當前目錄更改成根目錄

5關閉沒必要要的文件描述符

6忽略SIGCHID信號

生成守護進程代碼

#include <signal.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>

void my_daemon()
{
    int i;
    int fd0;
    pid_t pid;
    struct sigaction sa;
    umask(0); //設置文文件掩碼爲0
    if( (pid = fork()) < 0 )
    {

    }else if (pid != 0)
    {
        exit(0); //終止止父父進程
    }
    setsid(); //設置新會話
    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if( sigaction(SIGCHLD, &sa, NULL ) < 0 )
    { // 註冊子子進程退出忽略信號
        return;
    }
    if( (pid = fork())<0)
    {
     //再次fork,終止止父父進程,保持子子進程不是話首首進程,從而而保證後續    不會在和其餘終端關聯
        printf("fork error!\n");
        return;
    }else if( pid != 0)
    {
        exit(0);
    }
    if( chdir("/") < 0 )
    {//更改工工做目目錄到根
        printf("child dir error\n");
        return;
    }
    close(0);
    fd0 = open("/dev/null", O_RDWR); // 關閉標準輸入入,重定向全部標準(輸入入輸出錯誤)    到/dev/null
    dup2(fd0, 1);
    dup2(fd0, 2);
}
int main(int argc, char const *argv[])
{
    my_daemon();
    while(1)
        sleep(1);
    return 0;
}

注:以上代碼,是根據定義方式,本身實現的守護進程設置過程。

 

#include <stdio.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
    daemon(0,0);
    while(1);
    return 0;
}

這個則是系統中提供的設置守護進程的函數。

由圖咱們能夠看到,守護進程是脫離終端的。

相關文章
相關標籤/搜索