守护进程后台定时执行写文件操作以及信号操作指令简述

 以下代码实测可用,两次fork第一次生成守护进程pid,第二次生成GPID,同时SID继承GPID(进程组组长),时间读写可换其他文件操作

#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>

static bool flag = true;
void create_daemon();
void handler(int);

void handler(int sig)
{
    printf("I got a signal %d\nI'm quitting.\n", sig);
    flag = false;
}

int main()
{
    time_t t;
    int fd;
    create_daemon();

    struct sigaction act;//这里是一个信号处理的结构体
    act.sa_handler = handler;//后面调用handler函数
    sigemptyset(&act.sa_mask);//将sa_mask初始化为空集
    act.sa_flags = 0;//不设置特殊标志,意味着在 handler 函数执行期间,不会自动阻塞任何信号。

    if(sigaction(SIGQUIT, &act, NULL))//SIGQUIT是系统中用于请求程序立即终止并可能生成core dump文件的信号,说明如果core dump或者立刻推出则执行handler函数
    {
        printf("sigaction error.\n");
        exit(0);
    }
//操作文件写入时间
    while(flag)
    {
        fd = open("/home/daemon.log", 
        O_WRONLY | O_CREAT | O_APPEND, 0644);
        if(fd == -1)
        {
            printf("open error\n");
        }

        t = time(0);
        char *buf = asctime(localtime(&t));//获取时间
        write(fd, buf, strlen(buf));
        close(fd);
        sleep(60);//每分钟写入一次
    }
    return 0;
}

void create_daemon()
{
    pid_t pid;
    pid = fork();

    if(pid == -1)
    {
        printf("fork error\n");
        exit(1);
    }
    else if(pid)//父进程退出
    {
        exit(0);
    }

    if(-1 == setsid())//创建新对话,该会话的会话ID是调用进程的PID,调用进程成为新会话的会话首领。调用setsid()的进程将成为新的进程组的组长,并且脱离原来的控制终端
    {
        printf("setsid error\n");
        exit(1);
    }

    pid = fork();
    if(pid == -1)
    {
        printf("fork error\n");
        exit(1);
    }
    else if(pid)
    {
        exit(0);
    }

    chdir("/");
    int i;
    for(i = 0; i < 3; ++i)
    {
        close(i);
    }
    umask(0);
    return;
}
  • 本例中的守护进程仍然会尝试在控制台上打印消息,但这在实际环境中是不可见的,因为标准输出和标准错误已被关闭。你可以通过重定向或日志记录来捕获这些输出。
  • 守护进程通常用于在后台运行,执行长期任务,如监控服务、定时任务等。
  • 守护进程在Linux系统中非常常见,但在其他操作系统上可能有所不同。

实际案例中最后将会关闭标准文件描述符

// 关闭标准文件描述符  
    close(STDIN_FILENO);  
    close(STDOUT_FILENO);  
    close(STDERR_FILENO);  
  
    // 可以在这里重定向标准输出和标准错误到日志文件等  

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值