2

让 c 程序在 Linux 上保持后台运行以及日志输出

 2 years ago
source link: http://i.lckiss.com/?p=7469
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

让 c 程序在 Linux 上保持后台运行以及日志输出

2021-08-29

一年前搞了个树莓派,弄了个风扇和 oled 脚本,今年无意中发现几次风扇并没有按理想的状态运行,就重新看了下脚本,发现以前运行时启动就会阻塞在那而且有很多 printf,我想大概就是这么个原因。于是想起来改造:

  • 脚本执行后创建守护进程后台运行
  • 将打印改为日志输出

经过几天验证,发现挺顺利的。因为我并不从事 C 相关开发,文末也贴上了更为详细的文章,这里直接给出解决方案。

#include <fcntl.h>
#include <unistd.h>
#include <syslog.h>

#define _PATH_DEVNULL "/dev/null"

int daemon(int nochdir, int noclose);

int main(void)
{
    //启用日志
    openlog("LOG_TAG", LOG_CONS | LOG_PID, 0);

    if (0 == daemon(1, 0))
    {
        //守护进程开启成功
        syslog(LOG_DEBUG, "daemon ok\n");
    }
    else
    {
        //守护进程开启失败
        syslog(LOG_ERR, "daemon failed\n");
    }

    while (1)
    {
        //TODO 做一些常驻内存或者轮询的事
    }

    //关闭日志
    closelog();

    return 0;
}

int daemon(nochdir, noclose) int nochdir, noclose;
{
    int fd;

    switch (fork())
    {
    case -1:
        return (-1);
    case 0:
        break;
    default:
        _exit(0);
    }

    if (setsid() == -1)
        return (-1);

    if (!nochdir)
        (void)chdir("/");

    if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1)
    {
        (void)dup2(fd, STDIN_FILENO);
        (void)dup2(fd, STDOUT_FILENO);
        (void)dup2(fd, STDERR_FILENO);
        if (fd > 2)
            (void)close(fd);
    }
    return (0);
}

值得一提的是日志输出中 syslog 并不通用,我这边环境为 Ubuntu,这种日志是输出到/var/log/syslog文件的,我选择它的原因是它最为简单。

daemon 函数参数解释:第一个参数是指是否需要将工作空间切换至/,一般是不需要的,第二个参数是指是否需要将输出流转向到/dev/null,所以:

daemon 函数的参数请传 1,0 ,不然即使在后台运行,print 之类的还是会输出到当前控制台,仅在调试时传 1,1

另外任务什么的就把代码块放在 while(1) 中去做吧。

如何让程序真正地后台运行?

linux下C编程打印log


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK