Linux--守護進程(精靈進程)

守護進程(daemon)

   瞭解守護進程必須要先了解進程組、作業、會話,這三個概念已經在上一篇blog中介紹過了。

1.定義

守護進程獨立於控制端並週期性地執行某種任務或等待處理髮生的某些事件 ;

2.特點:

①守護進程的命名都是以d結尾;

②守護進程不受用戶登錄和註銷的影響,當會話終止時,後臺登錄和註銷受到影響,但不影響守護進程;

③守護進程的PPID即父進程都爲1,大部分守護進程的PID,PGID,SID都相同;

④所有的守護進程自成進程組,自成會話,所以它們的PID,PGID,SID相同;

⑤大部分的守護進程都是孤兒進程;

⑥守護進程完成許多系統任務,Linux的大多數服務器都是用守護進程實現的;

如圖所示:
這裏寫圖片描述

3 . 創建守護進程的函數:

pid_t setsid(void);

函數返回值:調用成功時,返回當前進程的ID,出錯時返回-1;

使用函數的條件:當前進程不能爲進程組長,所以可以先fork( )一個子進程,再調用這個函數,該子進程不可能爲進程組的首進程,即不可能爲進程組長;

4.爲什麼守護進程的父進程都爲一號進程?

由setsid()的使用條件可知,必須要先fork( )一個子進程,fork()完後將父進程退出,子進程被一號進程回收,它的PPID就爲1,所以所有守護進程的父進程都爲一號進程。

5.創建守護進程的步驟:

①調用umask將文件模式創建屏蔽字設置爲0;

②調用fork( ),並退出父進程;

③調用setsid( )創建一個新的會話;

④將當前工作目錄更改爲根目錄;

⑤關閉終端描述符,因爲守護進程與終端無關;

⑥忽略SIGCHLD信號;

6.自己創建守護進程:

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

void mydaemon()
{
    umask(0);//①文件模式創建屏蔽字設置爲0;
    if(fork()>0)//②調用fork( ),並退出父進程;
    {
        exit(0);
    }
    setsid();//③調用setsid( )創建一個新的會話;
    chdir("/");//④將當前工作目錄更改爲根目錄;
    close(0);//⑤關閉終端描述符;
    close(1);
    close(2);
    signal(SIGCHLD,SIG_IGN);//⑥忽略SIGCHLD信號;
}
int main()
{
    mydaemon();
    //還可以直接調用系統的deamon(0,0);
    while(1);
}

7.爲何有時會fork( )兩次?

(1) 第一次fork( )的作用:
①保證子進程不是組長進程,就可以調用setsid()創建會話;
②父進程退出後,讓shell認爲該命令已經執行完畢;

(2)第二次fork( )的作用:
防止進程打開了新的控制終端。
** 因爲打開一個新的終端的前臺條件是該進程是會話首進程,第二次fork( )後,產生子進程,父進程退出,不會是會話首進程,也就無法打開控制終端。
** 第二次的fork( )是可選的,不是必要的。

8.

所以,守護進程也叫作精靈進程,是運行在後臺的一個特殊進程,是一個很有用的進程,和以前學習的殭屍進程完全不同,它能夠完成許多系統任務,可以繼續瞭解它。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章