【问题标题】:How to use the pidfile library correctly?如何正确使用pidfile库?
【发布时间】:2011-04-12 00:58:03
【问题描述】:

我已经阅读了 pidfile 函数系列的手册页。但我真的不明白。正确的用法是什么?是否有更详细的示例可用?我想我理解pidfile_open。但是我什么时候应该打电话给pidfile_writeprdfile_close?来自哪个过程?父母还是孩子?我必须将哪些参数传递给这些函数?我猜我可能缺乏一些 *nix 基础知识。

更新:

下面是 man pidfile 中的示例。为什么他们分叉两次?为什么要使用 pidfile_close?当我调用 pidfile_close 时,我可以启动另一个守护进程。这不是不需要的吗?

 struct pidfh *pfh;
 pid_t otherpid, childpid;

 pfh = pidfile_open("/var/run/daemon.pid", 0600, &otherpid);
 if (pfh == NULL) {
         if (errno == EEXIST) {
                 errx(EXIT_FAILURE, "Daemon already running, pid: %jd.",
                     (intmax_t)otherpid);
         }
         /* If we cannot create pidfile from other reasons, only warn. */
         warn("Cannot open or create pidfile");
 }

 if (daemon(0, 0) == -1) {
         warn("Cannot daemonize");
         pidfile_remove(pfh);
         exit(EXIT_FAILURE);
 }

 pidfile_write(pfh);

 for (;;) {
         /* Do work. */
         childpid = fork();
         switch (childpid) {
         case -1:
                 syslog(LOG_ERR, "Cannot fork(): %s.", strerror(errno));
                 break;
         case 0:
                 pidfile_close(pfh);
                 /* Do child work. */
                 break;
         default:
                 syslog(LOG_INFO, "Child %jd started.", (intmax_t)childpid);
                 break;
         }
 }

 pidfile_remove(pfh);
 exit(EXIT_SUCCESS);

【问题讨论】:

  • 您看到的手册页是否有“示例”部分? BSD 可以,这很好地说明了常见用途。请参阅fuse4bsd.creo.hu/localcgi/man-cgi.cgi?pidfile+3,查看“示例”部分。
  • @Tim,手册页包含一个示例,但我无法将其应用于我的守护程序代码。我的守护进程结构不同。例如我不使用函数 daemon(3)。

标签: c linux unix daemon pid


【解决方案1】:

问题是您想在生成守护进程之前给出错误消息,并且在生成守护进程之后知道 PID 文件。

因此,您通常会在分叉之前执行 pidfile_open,这样您就有可能给出错误消息。分叉后,你知道了pidfile,你可以做pidfile_write。

【讨论】:

  • 为什么还要分叉? daemon() 分叉,不是吗?为什么要进行第二次分叉?
  • 是的,daemon() 分叉。我的意思是那个叉子,没有第二个叉子。所以你调用 pidfile_open()、daemon()、pidfile_write()、pidfile_close()。这样,您可以将 pidfile_open() 中的任何错误输出到终端(在分离之前)并写入子进程的 PID,这只有在调用 daemon() 后才知道。
  • 哦,我以为你指的是 man pidfile 中的示例代码。因为在 daemon() 之后完成了“第二个”分叉。你知道为什么吗?
  • @FairDinkumThinkum 在某些系统上需要第二个 fork 以确保守护进程与终端分离,它也使最终守护进程不再是会话领导者。另见stackoverflow.com/questions/1740308/…
【解决方案2】:

您在进入后台之前执行 pidfile_open(3),因此您可以立即报告任何问题。您还没有编写 PID,因为您的 PID 将在 daemon(3) 之后更改。 pidfile_open(3) 只锁定 pidfile。在 daemon(3) 之后,您可以调用 pidfile_write(3),因为您现在有了最终的 PID(daemon(3) 在内部分叉)。在主进程中,您不能调用 pidfile_close(3),因为这是整个想法 - 通过保持 pidfile 打开和锁定,您可以让其他人知道您还活着。第二个叉子是完全可选的。它说明了守护进程产生子/工作进程的常见行为。如果你不使用它们,你就不需要这个 fork()。这个 fork() 只是为了表明在这样的工作进程中你应该关闭 pidfile,所以它只被主进程而不是子进程保持打开和锁定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    • 1970-01-01
    • 2017-05-08
    • 2010-12-02
    相关资源
    最近更新 更多