Linux 守護進程的原理與實現

目錄

1 守護進程

2 創建守護進程流程

3 代碼示例


1 守護進程

      守護進程:也稱爲精靈進程,守護進程是一個在後臺運行並且不受任何終端控制的進程。守護進程脫離於終端是爲了避免進程在執行過程中的信息在任何終端上顯示並且進程也不會被任何終端所產生的終端信息所打斷。

2 創建守護進程流程

(1)創建子進程,退出父進程:爲了脫離控制終端需要退出父進程,之後的工作都由子進程完成。在Linux中父進程先於子進程退出會造成子進程成爲孤兒進程,而每當系統發現一個孤兒進程時,就會自動由1號進程(init)收養它,
這樣,原先的子進程就會變成init進程的子進程。

(2)在子進程中創建新的會話:使用setsid函數創建一個新的會話,並擔任該會話組的組長,主要作用如下:

  • 讓進程擺脫原會話的控制;
  • 讓進程擺脫原進程組的控制;
  • 讓進程擺脫原控制終端的控制;

(3)改變當前目錄爲根目:使用fork創建的子進程繼承了父進程的當前工作目錄。由於在進程運行中,當前目錄所在的文件系統(如“/mnt/usb”)是不能卸載的,這對以後的使用會造成諸多的麻煩(比如系統由於某種原因要進入單用戶模式)。因此,通常的做法是讓"/"作爲守護進程的當前工作目錄,這樣就可以避免上述的問題,當然,如有特殊需要,也可以把當前工作目錄換成其他的路徑,如/tmp。改變工作目錄的常見函數式chdir。

(4)重設文件權限掩碼:由於fork函數創建的子進程繼承了父進程的文件權限掩碼,這就給子進程使用文件帶來了諸多的麻煩。因此,把文件權限掩碼設置爲0(即,不屏蔽任何權限),可以增強該守護進程的靈活性。設置文件權限掩碼的函數是umask。通常的使用方法爲umask(0)。文件權限掩碼:是指屏蔽掉文件權限中的對應位。

(5)關閉文件描述符:用fork創建的子進程也會從父進程那裏繼承一些已經打開了的文件。在使用setsid調用之後,守護進程已經與所屬的控制終端失去了聯繫,因此從終端輸入的字符不可能達到守護進程,守護進程中用常規方法(如printf)輸出的字符也不可能在終端上顯示出來。所以,文件描述符爲0、1、2(即,標準輸入、標準輸出、標準錯誤輸出)的三個文件已經失去了存在的價值,也應該關閉。

(6)守護進程退出處理(可選):當用戶需要外部停止守護進程運行時,往往會使用 kill命令停止該守護進程。所以,守護進程中需要編碼來實現kill發出的signal信號處理,達到進程的正常退出。

3 代碼示例

本演示代碼每隔10s在/tmp/dameon.log中寫入一個“open”。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
#include <signal.h>
#define MAXFILE 65535
 
volatile sig_atomic_t _running = 1;
 
void sigterm_handler(int arg)
{
	_running = 0;
}
 
int main()
{
	pid_t pc, pid;
	int i, fd, len;
	char *buf = "this is a Dameon\n";
	len = strlen(buf);
	//第一步
	pc = fork();
	if(pc < 0)
	{
		printf("error fork\n");
		exit(1);
	}
	else if(pc > 0)
	{
		exit(0);
	}
	//第二步
	setsid();
	pid = fork();//與終端完全脫離[1]
	if (pid < 0)
	{
		perror("fork error");
	}
	if (pid > 0)
	{
		exit(0);
	}
	//第三步
	chdir("/");
	//第四步
	umask(0);
	//第五步
	for(i = 0;i < MAXFILE; i++)
	{
		close(i);
	}
	signal(SIGTERM, sigterm_handler);
	while( _running )
	{
		if((fd = open("/tmp/dameon.log", O_CREAT | O_WRONLY | O_APPEND, 0600)) < 0)
		{
			perror("open");
			exit(1);
		}
		write(fd, buf, len);
		close(fd);
		usleep(10 * 1000);//10毫秒
	}
}

 

 

 

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