用 C 创建一个具有停止、启动功能的守护进程

发布于 2024-09-24 01:25:33 字数 1506 浏览 0 评论 0原文

如何在该守护进程代码中添加守护进程停止、启动和报告功能?

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

int main(void) {

        /* Our process ID and Session ID */
        pid_t pid, sid;

        /* Fork off the parent process */
        pid = fork();
        if (pid < 0) {
                exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then
           we can exit the parent process. */
        if (pid > 0) {
                exit(EXIT_SUCCESS);
        }

        /* Change the file mode mask */
        umask(0);

        /* Open any logs here */        

        /* Create a new SID for the child process */
        sid = setsid();
        if (sid < 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
        }



        /* Change the current working directory */
        if ((chdir("/")) < 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
        }

        /* Close out the standard file descriptors */
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);

        /* Daemon-specific initialization goes here */

        /* The Big Loop */
        while (1) {
           /* Do some task here ... */

           sleep(30); /* wait 30 seconds */
        }
   exit(EXIT_SUCCESS);
}

How to add daemon stop, start and report function to this daemon code?

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

int main(void) {

        /* Our process ID and Session ID */
        pid_t pid, sid;

        /* Fork off the parent process */
        pid = fork();
        if (pid < 0) {
                exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then
           we can exit the parent process. */
        if (pid > 0) {
                exit(EXIT_SUCCESS);
        }

        /* Change the file mode mask */
        umask(0);

        /* Open any logs here */        

        /* Create a new SID for the child process */
        sid = setsid();
        if (sid < 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
        }



        /* Change the current working directory */
        if ((chdir("/")) < 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
        }

        /* Close out the standard file descriptors */
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);

        /* Daemon-specific initialization goes here */

        /* The Big Loop */
        while (1) {
           /* Do some task here ... */

           sleep(30); /* wait 30 seconds */
        }
   exit(EXIT_SUCCESS);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

攒眉千度 2024-10-01 01:25:33
  1. 将守护进程的pid写入/var/run/mydaemonname.pid,以便以后方便查找pid。
  2. 为 SIGUSR1 和 SIGUSR2 设置信号处理程序。
  3. 当收到 SIGUSR1 时,切换停止标志。
  4. 当收到 SIGUSR2 时,设置报告标志。
  5. 在 while 循环中,检查每个标志。
  6. 如果设置了停止标志,则停止直至其被清除。
  7. 如果设置了报告标志,请清除该标志并进行报告。

停止/启动存在一些复杂性,但如果我正确理解了这个问题,这应该会让您走上正确的轨道。

编辑:按照 Dummy00001 在下面的评论中的建议添加了 pid 文件。

  1. Write the pid of the daemon to /var/run/mydaemonname.pid so that you can easily look up the pid later.
  2. Set up a signal handler for SIGUSR1 and SIGUSR2.
  3. When you get SIGUSR1, toggle a stop flag.
  4. When you get SIGUSR2, set a report flag.
  5. In your while loop, check each flag.
  6. If the stop flag is set, stop until it is cleared.
  7. If the report flag it set, clear the flag and do your report.

There are some complications around stop/start, but if I'm understanding the question correctly, this should get you on the right track.

Edit: Added pid file as suggested by Dummy00001 in a comment below.

梦罢 2024-10-01 01:25:33

首先,您可能不必自己做那么多的分叉和整理工作: http://linux .die.net/man/3/daemon

接下来,请记住,您的守护进程与世界的接口可能是通过某种 shell 脚本来实现的,您也可以在 /etc/init.d 或任何其他发行版定义的位置编写该脚本地方。

因此,对于上述答案,您的 shell 脚本会将这些信号发送到进程的 pid。但可能有更好的方法。像上面这样的信号是一个单向过程,您的控制脚本必须跳过容易出现竞争条件且脆弱的循环,以确认守护进程是否成功停止或重新启动。我会在 /etc/init.d 中查找优先级和示例。

First, you probably don't have to do so much forking and house keeping yourself: http://linux.die.net/man/3/daemon

Next, remember that your daemon's interface to the world is probably through some sort of shell script that you also write located in /etc/init.d or whatever other distro-defined place.

So for the above answer, your shell script would send those signals to the pid of the process. There probably is a better way though. Signaling like above is a one way process, your controlling script has to jump through race-condition-prone and fragile hoops in order to confirm if the daemon successfully stopped or restarted. I would look for precedence and examples in /etc/init.d.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文