Linux编程之会话与守护进程

什么是会话?我们知道一个进程有组id,当多个进程的组id相同时,我们称这些进程隶属于同一个进程组,而会话则是由进程组组成的,会话也有会话id,我们通过ps ajx可以看到一栏名为sid,这个sid就是会话id。

我们可以通过setsid函数来将一个进程脱离原有的会话,建立新的会话。但是,要想该函数调用成功,需要注意以下2点:

1. 调用进程不能是进程组的组长,否则会出错

2. 需要root权限,但ubuntu不需要

当我们调用成功后,通过ps ajx可以发现调用进程的tty那一栏变成了?,也就是说该进程已经没有和控制终端绑定了。我们知道当我们在终端上执行一个程序的时候,直接退出终端,会结束掉我们的进程,这是因为我们的程序是和控制终端进程绑定的,当控制终端结束时,会终止和它绑定的所有进程,也就是与控制终端同一会话的都会被终止。那么,该进程脱离了控制终端,则终端结束,该进程也不会结束。

什么是守护进程?守护进程就相当于windows中的服务程序,周期性的执行某种任务或等待处理某些发生的事件。守护进程是独立的,脱离了控制终端的,而且都是长时间运行在后台的。

那么如何创建一个守护进程的,有以下几个基本步骤:

1.创建子进程,父进程退出。这样我们就能保证该进程不可能是进程组组长。

2.在子进程中创建新的会话。这就把子进程脱离了控制终端

3.改变当前工作目录。主要是为了防止占用可卸载的文件系统

4.重设文件权限掩码。防止继承的文件创建屏蔽字拒绝某些权限,增加守护进程灵活性。

5.关闭文件描述符。因为已经脱离了控制终端,所以哪些标准输入输出已经不会用到。

6.开始执行守护进程的核心工作。

7.守护进程退出处理。

以下是一个守护进程的示例代码,它每个10s会向当前目录下的time.log文件写入当前时间:

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

void daemonize(void)
{
	pid_t pid;
	
	if((pid = fork()) < 0)
	{
		perror("fork");
		exit(1);
	}
	else if(pid != 0) 
	{		
		exit(0);
	}
	setsid();
	
	if(chdir("/") < 0)
	{
		perror("chdir");
		exit(1);
	}
	
	umask(0);
	
	close(0);
	open("/dev/null",O_RDWR);
	dup2(0,1);
	dup2(0,2);
}

int main(void)
{
	int fd = open("./time.log",O_RDWR | O_APPEND | O_CREAT,0777);
	if(fd < 0)
	{
		perror("open");
		exit(1);
	}
	time_t t;
	char buf[1024];
	bzero(buf,sizeof(buf));
	daemonize();

	while(1)
	{
		time(&t);
		ctime_r(&t,buf);
		
		write(fd,buf,strlen(buf));

		sleep(10);
	}
	return 0;
}

你可能感兴趣的:(linux,守护进程,linux会话,setsid,守护进程实现,ctime_r)