Linux-守护进程

在介绍守护进程之前首先介绍三个概念:

  1. 进程组:进程组是一个或多个进程的集合。每个进程除了有一个进程ID之外,还属于一个进程组。每个进程组有一个唯一的进程组ID。每个进程组都可以有一个组长进程,组长进程的标识是:进程组ID等于组长进程ID。只要某个进程组中有一个进程存在,该进程组就存在,与组长进程是否存在无关。
  2. 作业:Shell分前后台控制的不是进程而是作业或者进程组,shell可以运行一个前台作业和任意多个后台作业。作业和进程组的区别:如果作业中的某个进程又创建了子进程,则子进程不属于作业。
  3. 会话:会话是一个或多个进程组的集合。一个会话中应该包括控制进程(会话首进程bash),一个前台进程组和任意个后台进程组。

下面介绍守护进程

    守护进程不受用户登录和注销的影响,他们一直运行着。由此可以看出守护进程自成会话,自成进程组。

    如何创建一个守护进程?

   1. 创建守护进程关键的一步是调用setsid函数来创建一个会话。

#include
pid_t setsid(void)

    调用成功返回新创建的会话的ID,出错返回-1。调用这个函数之前,当前进程不允许是进程组的Leader,否则返回-1。

    2.自己编写代码创建守护进程:

#include
#include
#include
#include
#include
#include

void mydaemon(void)
{
	int i;
	int fd0;
	pid_t pid;
	struct sigaction sa;
	
	//1.调用umask将文件模式创建屏蔽字设置为0
	umask(0);
	//2.调用fork,父进程退出
	//保证子进程不是一个进程组的组长进程
	if((pid=fork())<0){
		perror("fork");
	}else if(pid>0){
		exit(0);
	}
	//3.调用setsid创建一个新会话
	setsid();
	//4.忽略SIGCHLD信号
	sa.sa_handler=SIG_IGN;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags=0;
	if(sigaction(SIGCHLD,&sa,NULL)<0){//注册子进程退出忽略信号
		return ;
	}
	//再次fork,终止父进程,保持子进程不是会话首进程,从而保证后续不会在和其他终端关联。
	if((pid=fork())<0){
		printf("fork error\n");
		return ;
	}else if(pid!=0){
		exit(0);
	}
	//5.将工作目录更改到根目录
	if(chdir("/")<0){
		printf("child dir error\n");
		return ;
	}
	//关闭不在需要的文件描述符,或者重定向到/dev/null
	close(0);
	fd0=open("/dev/null",O_RDWR);
	dup2(fd0,1);
	dup2(fd0,2);

}
int main()
{
	mydaemon();
	while(1)
	{
		sleep(1);
	}

}

运行结果:

Linux-守护进程_第1张图片

Linux-守护进程_第2张图片

打开两个终端发现./a.out进程都存在,所以守护进程创建成功。

你可能感兴趣的:(Linux)