一年前搞了个树莓派,弄了个风扇和 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) 中去做吧。
参考:
本站广告由 Google AdSense 提供
0条评论