守護進程也稱精靈進程,是運行在後台的一種特殊進程。他獨立於終端並且周期性執行某種任務或者等待某件事情的發生。守護進程是一種很有用的進程。比如很多的服務器都是以次方是運行在後台,等待客戶端連接並處理相關問題的。
系統中守護進程通常以d結尾標識。
創建守護進程關鍵的一步是調用setsid函數創建一個新的會話,並使之稱為控制進程。
注:調用setsid創建守護進程的當前進程不得是進程組的leader,否則返回-1;保證這個條件的方式是:我們在當前進程進行fork生成子進程,父進程直接退出,子進程調用setsid就可以了。
1。創建一個新的會話,並且當前進程稱為leader,當前進程id為會話id
2。創建一個新的進程組,當前進程是進程組的leader,當前進程id就是進程組id
3。如果當前進程原本有一個控制終端,那麼他失去這個終端稱為一個沒有終端控制的進程。
1調用umask將文件屏蔽字設置為0
2調用fork,父進程退出
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;
}
這個則是系統中提供的設置守護進程的函數。

由圖我們可以看到,守護進程是脫離終端的。
http://xxxxxx/Linuxjc/1144281.html TechArticle