代码之家  ›  专栏  ›  技术社区  ›  Azeem Michael

C守护进程睡眠()

  •  2
  • Azeem Michael  · 技术社区  · 14 年前

    我正在用c++运行一个简单的守护程序测试。如果没有sleep()函数,它运行得很好,但是如果我添加sleep()函数,它只运行一次,就可以保持睡眠。此外,第一次运行应该在日志中打印一次“Hello”/日志.dat但那也不会发生。代码如下:

     #include <cstdlib>  
     #include <cstdio>  
     #include <iostream>  
     #include <unistd.h>  
     using namespace std;  
     int main(int argc, char** argv) {  
        FILE *f = NULL;   
        if ((f = fopen("logs/log.dat  ", "w")) != NULL) {  
            if (daemon(0, 0) >= 0) {  
                while (true) {  
                    fprintf(f, "%s\n", "Hello");  
                    sleep(5);  
                }  
            } else {  
                fprintf(f, "%s\n", "Error detaching terminal");  
            }  
        } else {  
            printf("%s\n", "Cannot open log file");  
        }  
        return 0;  
    }
    
    3 回复  |  直到 14 年前
        1
  •  5
  •   Jay    14 年前

    尝试在fprintf()之后添加fflush()。它可能正在工作,但尚未将数据写入磁盘。

        2
  •  3
  •   Jonathan Leffler    14 年前

    房间里有什么 daemon() 功能?特别是,它是否关闭标准输入、标准输出和标准错误以外的打开文件?如果是,那么 fprintf() 守护程序() 之后关闭。

    如果您的代码测试了打印函数的返回值,您将能够发现这一点(尽管您可能必须打开一个带有绝对路径名的日志文件才能从守护进程报告它)。

    注意有些 守护程序()


    在MacOS X上 daemon(3) <stdlib.h>

    简介

    #include <stdlib.h>
    
     int
     daemon(int nochdir, int noclose);
    

    说明

    daemon()函数用于希望从控制终端分离自己的程序 作为系统守护进程在后台运行。[...]

    除非参数noclose非零,否则daemon()将标准输入、标准输出和标准错误重定向到/dev/null。


    FreeBSD 8 源代码。

    自从打电话给 守护程序() 两次传递0,代码执行 chdir("/") fork(2) setsid(2) . 因此,我们可以适度确信您的程序已将其标准I/O通道重新连接到/dev/null,并且当前目录已更改为根目录。

    这还不能解释文件中缺少数据的原因,也不能解释为什么 sleep() 影响结果。当然,经典的 摆弄信号和信号;手册页 守护进程(3) sleep(3) 使用 nanosleep(2) 系统调用。

    因此,我同意Jay的建议-文件将被完全缓冲,您必须等待大量的5秒周期来打印足够的数据以刷新缓冲区(可能需要4096字节,每5秒6字节,大约需要一个小时才能生成文件中的任何内容)。添加 fflush() setvbuf(f, 0, _IONBF, 0); 关闭所有缓冲,或 setvbuf(f, 0, _IOLBF, BUFSIZ); 启用行缓冲。以及 睡眠()

        3
  •  0
  •   MBI    10 年前

    我也遇到了类似的问题,但是因为我使用了syslog,所以使用fflush()是不可能的。 在我的例子中,解决方案是更改调试消息。

    syslog(LOG_DEBUG, "DEBUG: tick");
    

    收件人:

    syslog(LOG_DEBUG, "DEBUG: tick %d", i); // i is increased in the loop
    

    所以每次都有不同的信息。