Linux C编程:守护进程(Daemon进程)

目录

1.特点:

2.终端:

3.守护进程的实现:

4.守护进程代码实例1:

5.守护进程的出错处理(系统日志)


1.特点:

        1》生成时间较长:系统启动开始运行,系统关闭时结束;
        2》通常独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件;

2.终端:

        在linux中,每一个系统与用户进行交流的界面称为终端。
        每一个次从终端开始进行的进程都会依附于这终端,这个终端就称为这些进程的控制终端,当终端被关闭时,相应的进程都会被自动关闭;

3.守护进程的实现:

        (1).进程第1次fork,为进程调用setsid做准备;
        (2).进程调用setsid,进程成为新的会话过程的领头进程;
        (3).忽略信号SIGHUP,第2次fork,使进程成为一个新的进程组的领导者。
        (4).关闭所有的文件描述符。
        (5).消除umask的影响。
        (6).修改守护进程的当前目录。
        (7).重新定位标准I/O描述符。

4.守护进程代码实例1:

/*******************************************************************
 *   > File Name: daemon_process.c
 *   > Create Time: 2021-03-01  1/09  12:42:07 +0800
 *================================================================*/

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

void init_daemon(void){
    pid_t pid;
    int i;

    pid = fork();
    if(pid < 0)
    {
        printf("Error Fork\n");
        exit(1);
    }
    else if(pid > 0)
    {
        exit(0);
    }

    setsid();
    chdir("/tmp");
    umask(0);

    for(i = 0; i< getdtablesize(); i++)
    {
        close(i);
    }
}

int main(int argc, char* argv[])
{
    init_daemon();

    int fd;
    char *buf = "This is Daemon\n";

    while(1)
    {
        if((fd = open("daemon.log", O_CREAT|O_WRONLY|O_APPEND, 0600)) <0)
        {
            printf("Open file error.\n");
            exit(1);
        }

        write(fd, buf, strlen(buf));
        close(fd);
        sleep(2);
    }

    return 0;
}

编译后运行,在"/tmp"目录下,输入:cat daemon.log

查看运行结果:

This is Daemon
This is Daemon

5.守护进程的出错处理(系统日志)

由于守护进程完全脱离了控制终端,不能像普通进程将错误信息输出到控制终端;

调试办法是使用syslog服务,将程序中的出错信息输入到系统日志文件中(“/var/log/syslog”),从而查找程序的问题所在;

       #include <syslog.h>

       void openlog(const char *ident, int option, int facility);//打开系统日志服务的一个连接;
       void syslog(int priority, const char *format, ...);//向日志文件中写入消息,在这里可以规定消息的优先级、消息输出格式等;
       void closelog(void);//关闭系统日志服务的连接

       void vsyslog(int priority, const char *format, va_list ap);

/*******************************************************************
 *   > File Name: daemon_syslog.c
 *   > Create Time: 2021-03-01  1/09  12:42:07 +0800
 *================================================================*/

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <syslog.h>

void init_daemon(void){
    pid_t pid;
    int i;

    pid = fork();
    if(pid < 0)
    {
        printf("Error Fork\n");
        exit(1);
    }
    else if(pid > 0)
    {
        exit(0);
    }

    setsid();
    chdir("/");
    umask(0);

    for(i = 0; i< getdtablesize(); i++)
    {
        close(i);
    }
}

int main(int argc, char* argv[])
{
    init_daemon();

    int fd;
    char *buf = "This is Daemon";
    char str_buf[128] = {0};
    time_t timep;
    
    openlog("daemon_syslog", LOG_PID|LOG_PERROR, LOG_DAEMON);
    while(1)
    {
        if((fd = open("/opt/daemon.log", O_CREAT|O_WRONLY|O_TRUNC, 0600)) <0)
        {
            printf("Open file error.\n");
            syslog(LOG_ERR, "open");
            syslog(LOG_ERR, "daemon syslog test");
            exit(1);
        }

        bzero(str_buf, 128);
        time(&timep);
        snprintf(str_buf, 128, "%s :%s ", buf, ctime(&timep));

        write(fd, str_buf, strlen(str_buf));
        close(fd);
        sleep(2);
    }

    closelog();

    return 0;
}

普通用户身份执行程序,由于open打开/opt目录需要root权限,导致程序运行时无法打开文件退出,可以在日志文件中查看执行时的输出信息;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值