守护进程的概念和创建步骤

在这里插入图片描述

1. 进程组

也称之为作业。进程组ID等于第一个进程ID,因此可以通过进程ID是否等于进程组ID来判断该进程是不是进程组的组长。

只要进程组中有一个进程存在,进程组就存在,哪怕组长已经没了。

一个进程可以为自己或子进程设置进程组ID

2. 会话

由多个进程组组成。
创建会话要注意以下5点:

  1. 调用进程不能是进程组组长,该进程变成新会话首进程(session header)
  2. 该进程成为一个新进程组的组长进程。
  3. 新会话丢弃原有的控制终端,该会话没有控制终端。
  4. 该调用进程是组长进程,则出错返回。
  5. 建立新会话时,先调动fork,父进程终止,子进程调用setsid(setsid后子进程不受终端影响,终端退出,不影响子进程)。
man 2 setsid

在这里插入图片描述

3. 守护进程

守护进程常常以“d”结尾
在这里插入图片描述

3.1 创建守护进程模型

创建守护进程最关键的一步就是调用setsid函数创建一个新的Session,并成为Session Leader

  1. 创建子进程,父进程退出
    所有工作在子进程中进行,形式上脱离了控制终端
  2. 在子进程中创建新会话
    setsid()函数
    使子进程完全独立出来,脱离控制
  3. 改变当前目录为根目录
    chdir()函数
    防止占用可卸载的文件系统
    也可以换成其他路径
  4. 重设文件权限掩码
    umask()函数
    防止继承的文件创建屏蔽字拒绝某些权限
    增加守护进程的灵活性
  5. 关闭文件描述符
  6. 开始执行守护进程核心工作
  7. 守护进程退出处理程序模型

其中,3、4、5步不必要

3.2 守护进程的步骤

  1. 创建子进程fork
  2. 父进程退出
  3. 子进程当会长setsid
  4. 切换工作目录$HOME
  5. 设置掩码umask
  6. 关闭文件描述符0,1,2,为了避免浪费资源
  7. 执行核心逻辑

3.3 创建一个守护进程实例:每份中在$HOME/log/ 创建一个文件 ,文件名—— 程序名.时间戳

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/time.h>
#include<time.h>
 
//通过宏定义文件名
#define _FILE_NAME_FORMAT_ "%s/log/mydaemon.%ld" //定义文件格式化
 
void touchfile(int num){
	//获取家目录
	char *HomeDir=getenv("HOME");
	char strFilename[250]={0};
	//获取时间戳的函数
	//time(NULL);
	sprintf(strFilename, _FILE_NAME_FORMAT_, HomeDir, time(NULL));
 
	int fd=open(strFilename, O_RDWR|O_CREAT, 0666);
	//文件打开失败
	if(fd<0){
		perror("open err");
		exit(1);
	}
	close(fd);
}
 
int main(){
	//创建守护进程的步骤如下
	//创建子进程,父进程退出
	pid_t pid=fork();
	if(pid>0){
		exit(1);
	}
	//当会长
	setsid();
	//设置掩码
	umask(0);
	//切换目录
	//getenv获取环境变量
	chdir(getenv("HOME"));//切换到家目录
	//关闭文件描述符(一般通过测试之后,才会关闭文件描述符)
	//close(0),close(1),close(2)
 
	//执行核心逻辑
	//设置一个定时器——每60秒来一次
	struct itimerval myit={{60,0},{60,0}};
	setitimer(ITIMER_REAL, &myit, NULL);
	//注册捕获函数
	struct sigaction act;
	act.sa_flags=0;
	//清空阻塞信号集
	sigemptyset(&act.sa_mask);
	//绑定捕获函数
	act.sa_handler=touchfile;
	//注册捕获函数
	sigaction(SIGALRM, &act, NULL);
	while(1){
		//每隔一分钟在/home/itheima/log创建文件
		sleep(1);
	}
	
	return 0;
}

3.4 nohup指令

指令nohup去执行进程就不会收到第一个信号
在这里插入图片描述
通过nohup指令也可以达到守护进程的创建效果。(可以把进程输出重定向到特定的地方)

  • nohup 指令会让cmd收不到SIGHUP信号
  • & 代表后台运行

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值