(五)Linux系统编程之守护进程

一、守护进程

1、守护进程的特点

  • 后台服务进程
  • 独立于控制终端【去掉依赖的终端】
  • 周期性执行某任务
  • 不受用户登录注销影响
  • 一般采用以d结尾的名字(服务)

2、进程组

  • 进程的组长?
    组里面的第一进程
    进程组的ID == 进程组的组长的ID【PID】

  • 进程组组长的选则
    进程中的第一个进程

  • 进程组ID的设定
    进程组的id就是组长的进程ID

在这里插入图片描述


3、会话 - 多个进程组

  • 创建一个会话注意事项:
    (1)不能是进程组长【其他进程才有机会创建会话】
    (2)创建会话的进程成为新进程组的组长
    (3)有些Linux版本需要root权限执行此操作(Ubuntu不需要)
    (4)创建出的新会话会丢弃原有的控制终端
    (5)一般步骤:先fork,父亲死,儿子执行创建会话操作(setsid)

  • 获取进程所属的会话ID
    pid_t getpid(pid_t pid);

  • 创建一个会话
    pid_t setsid(void);


4、创建守护进程模型

  • fork子进程,父进程退出【必须】

  • 子进程创建新会话【必须】
    setsid()

  • 改变当前工具目录chdir 【非必须】
    可能出现的情况:插入一个U盘,a.out,在U盘目录中启动a.out
    a.out启动过程中,U盘拔掉了
    为了解决这种的情况

  • 重设文件掩码【非必须】
    子进程会继承父进程的掩码
    增加子进程程序操作的灵活性
    umask(0);//无任何的限制

  • 关闭文件描述符【非必须】
    释放资源
    clse(0); close(1); close(2);

  • 执行核心工作【必须】


5、练习
写一个守护进程,每隔2s获取一次系统时间,将这个时间写入到磁盘文件
(1)创建守护进程
(2)需要一个定时器,2s触发一次

  • settimer
  • sleep

(3)信号捕捉

#include<fcntl.h>
#include<unistd.h>
#include<iostream>
#include<errno.h>
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/mman.h>
#include<signal.h>
#include<sys/time.h>

void dowork(int no)
{
        time_t curtime;
        //获取当前系统时间
        time(&curtime);
        //格式化时间
        char* pt=ctime(&curtime);
        //将时间写入文件
        int fd=open("/home/linux123/temp++++.txt",O_CREAT|O_WRONLY|O_APPEND,0664);
        write(fd,pt,strlen(pt)+1);
        close(fd);
}

int main(int argc,const char* argv[])
{
        pid_t pid=fork();

        if(pid>0)
        {
                //父进程退出
                exit(1);
        }
        else if(pid==0)
        {
                //变成会长 - 脱离终端控制
                setsid();

                //改变进程的工作目录
                chdir("/home");

                //重置文件掩码
                umask(0);

                //关闭文件描述符
                close(STDIN_FILENO);
                close(STDOUT_FILENO);
                close(STDERR_FILENO);

                //执行核心操作

                //注册捕捉信号,在信号发出来之前进行捕捉,否则信号发完,还没注册成功
                //signal();
                struct sigaction act;
                act.sa_flags=0;
                act.sa_handler=dowork;
                sigemptyset(&act.sa_mask);
                sigaction(SIGALRM,&act,NULL);
                //创建定时器
                struct itimerval val;
                //第一次触发的时间
                val.it_value.tv_usec=0;
                val.it_value.tv_sec=2;
                //循环周期
                val.it_interval.tv_usec=0;
                val.it_interval.tv_sec=2;

                setitimer(ITIMER_REAL,&val,NULL);
                //保证子进程处于运行状态
                while(1);
        }
        return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值