栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

浅谈守护进程

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

浅谈守护进程

文章目录
  • 一、守护进程是什么?
  • 二、创建守护进程的过程
    • 1.枯燥的概念
    • 2.直观的代码
  • 总结


一、守护进程是什么?

定义:脱离于终后台服务程序端,在后台独立运行的程序;
特点:

  • 独立控制终端,用户不需要和终端交互;
  • 周期性的执行某任务;
  • 不受用户登录注销的影响;
  • 一般采用d结尾的名字(服务)

了解了守护进程的基本概念之后,还需要了解两个知识点:进程组和会话

  1. 进程组
    一个或多个进程的集合;
    进程组ID作为唯一标识;
    组长进程是进程组的第一个进程;
    进程组的ID == 进程组的组长的ID;
  2. 会话
    会话是由多个进程组组成;
  3. 创建一个会话注意的事项
    *不能是组长进程;
    创建会话的进程成为新进程组的组长;
    创建的新会话会丢弃原有的控制终端;
    一般步骤:先fork(),父进程死,子进程创建会话(setsid());
    获取进程所属的会话ID
    pid_t setsid(pid_t pid);
    创建一个会话:
    pid_t setsid(void);
二、创建守护进程的过程 1.枯燥的概念
  1. 创建子进程,父进程退出;
  2. 子进程创建新的会话,调用setsid();
    setsid()函数的作用
  • 在上一步,调用fork()创建子进程,再将父进程退出;
  • 而在调用fork()时,子进程全盘拷贝了父进程的会话、进程组和控制终端,虽然父进程退出了,但是这些没有改变,因此还不是真正意义的独立开来;
  • 而setsid()可以使进程完全独立,从而摆脱其它进程的控制。
  1. 改变当前目录为根目录

  2. 重设文件权限掩码
    文件权限掩码是指屏蔽文件权限的对应位;
    比如,有一个文件的权限掩码是050,它就屏蔽了文件组的可读和可执行权限。

使用fork()新建的子进程继承了父进程的文件权限掩码,这会给子进程使用文件带来很多麻烦,因此把文件权限掩码设置为0 ,可以增强守护进程的灵活性,一般用umask(0);

  1. 关闭文件描述符
    与文件权限码一样,使用fork()创建的子进程会继承父进程的一些已经打开的文件,这些文件可能用于不会被守护进程读写,但是它们一直消耗系统资源。

在第2步之后,子进程即守护进程已经与所属终端断了联系;
因此,从终端输入的字符不可能到达守护进程,守护进程中用常规方法输出的字符也不可能在终端打印出来;
所以,文件描述符0(输入),1(输出),2(报错)已经失去了存在的价值,应该被关闭。

2.直观的代码

代码如下:

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

void func(int no);  // callback function
int main(int argc, char **argv)
{
	pid_t pid = fork();
	if(pid >0)
	{
		printf("parent process exitn");
		_exit(1);
	}
	else if(pid == 0)
	{
		setsid(); //child create session
		umask(0);
		
		close(STDIN_FILENO);   //close file descriptor
		close(STDOUT_FILENO);
		close(STDERR_FILENO);
		
		
		struct sigaction act;
        act.sa_flags = 0;
		act.sa_handler = func;
		sigaddset(&act.sa_mask, SIGQUIT);
		
		itimerval time;    //set timer
		time.it_value.tv_sec = 2;
		time.it_value.tv_usec = 0;
		time.it_interval.tv_sec = 1;
		time.it_interval.tv_usec = 0;
		
		sigaction(SIGVTALRM, &act, NULL);
		setitimer(ITIMER_VIRTUAL, &time, NULL);
 		
		while(true);
	}
	
	return 0;
}

void func(int no)
{
time_t currtime;
time(&currtime);
char* ptr = ctime(&currtime);


int fd = open("/home/fork/setsid.txt", O_CREAT | O_WRONLY | O_APPEND, 0777);
write(fd, ptr, sizeof(ptr)+1);
close(fd);

}
	

总结

这部分知识点有点枯燥啊,守护进程,孤儿进程,僵尸进程,继续努力,稍后再更新!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/892842.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号