在Linux中,我想添加一个无法停止的守护进程,用于监视文件系统的更改.

我已经准备好了文件系统更改代码,但我不知道如何创建守护进程.

我的密码是http://www.yolinux.com/TUTORIALS/ForkExecProcesses.html

fork 用完后怎么办?

int main (int argc, char **argv) {

  pid_t pID = fork();
  if (pID == 0)  {              // child
          // Code only executed by child process    
      sIdentifier = "Child Process: ";
    }
    else if (pID < 0) {
        cerr << "Failed to fork" << endl;
        exit(1);
       // Throw exception
    }
    else                                   // parent
    {
      // Code only executed by parent process

      sIdentifier = "Parent Process:";
    }       

    return 0;
}

推荐答案

在Linux中,我想添加一个无法停止的守护进程,该守护进程监视文件系统更改.如果检测到任何更改,它应该将启动时所在控制台的路径+换行符写入其中.

守护进程在后台工作,并且(通常…)不属于TTY这就是为什么你不能以你可能想要的方式使用stdout/stderr.

除此之外,还有几百种方法可以对一个进程进行后台监控.


如果我没记错,这些步骤是:

  • fork off the parent process & let it terminate if forking was successful. -> Because the parent process has terminated, the child process now runs in the background.
  • setsid-创建一个新会话.调用流程将成为新会话的负责人和新流程组的流程组长.该进程现在已与其控制终端(CTTY)分离.
  • Catch signals-忽略和/或处理信号.
  • fork again&;让父进程终止,以确保摆脱会话 bootstrap 进程.(只有会议负责人才能再次获得TTY.)
  • chdir-更改守护进程的工作目录.
  • umask-根据守护进程的需要更改文件模式掩码.
  • close-关闭可能从父进程继承的所有打开的文件描述符.

给您一个起点:看看这段显示基本步骤的框架代码.现在还可以在giHub:Basic skeleton of a linux daemon上派生此代码

/*
 * daemonize.c
 * This example daemonizes a process, writes a few log messages,
 * sleeps 20 seconds and terminates afterwards.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>

static void skeleton_daemon()
{
    pid_t pid;

    /* Fork off the parent process */
    pid = fork();

    /* An error occurred */
    if (pid < 0)
        exit(EXIT_FAILURE);

    /* Success: Let the parent terminate */
    if (pid > 0)
        exit(EXIT_SUCCESS);

    /* On success: The child process becomes session leader */
    if (setsid() < 0)
        exit(EXIT_FAILURE);

    /* Catch, ignore and handle signals */
    //TODO: Implement a working signal handler */
    signal(SIGCHLD, SIG_IGN);
    signal(SIGHUP, SIG_IGN);

    /* Fork off for the second time*/
    pid = fork();

    /* An error occurred */
    if (pid < 0)
        exit(EXIT_FAILURE);

    /* Success: Let the parent terminate */
    if (pid > 0)
        exit(EXIT_SUCCESS);

    /* Set new file permissions */
    umask(0);

    /* Change the working directory to the root directory */
    /* or another appropriated directory */
    chdir("/");

    /* Close all open file descriptors */
    int x;
    for (x = sysconf(_SC_OPEN_MAX); x>=0; x--)
    {
        close (x);
    }

    /* Open the log file */
    openlog ("firstdaemon", LOG_PID, LOG_DAEMON);
}
int main()
{
    skeleton_daemon();

    while (1)
    {
        //TODO: Insert daemon code here.
        syslog (LOG_NOTICE, "First daemon started.");
        sleep (20);
        break;
    }

    syslog (LOG_NOTICE, "First daemon terminated.");
    closelog();

    return EXIT_SUCCESS;
}


  • 编译代码:gcc -o firstdaemon daemonize.c
  • 启动守护进程:./firstdaemon
  • 判断是否一切正常:ps -xj | grep firstdaemon

  • 输出应与此类似:

+------+------+------+------+-----+-------+------+------+------+-----+
| PPID | PID  | PGID | SID  | TTY | TPGID | STAT | UID  | TIME | CMD |
+------+------+------+------+-----+-------+------+------+------+-----+
|    1 | 3387 | 3386 | 3386 | ?   |    -1 | S    | 1000 | 0:00 | ./  |
+------+------+------+------+-----+-------+------+------+------+-----+

What you should see here is:

  • 守护程序没有控制终端(TTY = ?)
  • 父进程ID(PPID)是1(init进程)
  • PID != SID,这意味着我们的流程不是会议负责人
  • 因为PID!=SID我们的流程can't take control of a TTY again

Reading the syslog:

  • 找到你的系统日志(log)文件.我的在这里:/var/log/syslog
  • a:grep firstdaemon /var/log/syslog

  • 输出应与此类似:

  firstdaemon[3387]: First daemon started.
  firstdaemon[3387]: First daemon terminated.


A note: In reality you would also want to implement a signal handler and set up the logging properly (Files, log levels...).

Further reading:

C++相关问答推荐

在C、Linux中同步进程

定义_MISIX_C_SAL时,在MacOS上编译失败,并出现奇怪错误

如何通过Zephyr(Devicetree)在PR Pico上设置UTE 1?

为什么下面的C代码会进入无限循环?

在C中使用动态内存分配找到最小的负数

将 struct 变量赋给自身(通过指针取消引用)是否定义了行为?

在C语言中,在数学运算过程中,为什么浮点数在变量中的行为不同

fwrite无法写入满(非常大)缓冲区

如果dim指定数组中的数据量,使用dim-1会不会潜在地导致丢失一个元素?

一旦运行长度超过2,编译器是否会优化";strnlen(mystring,32)>;2";以停止循环?

我不知道为什么它不能正常工作,我用了get()和fget(),结果是一样的

在运行时判断C/C++指针是否指向只读内存(在Linux操作系统中)

在吉陀罗中,_2_1_和CONCAT11是什么意思?

为什么我的旧式&q;函数在传递浮点数时会打印2?

如何使用calloc和snprintf

在C中,为什么这个带有递增整数的main函数从不因溢出而崩溃?

STM32:代码的执行似乎取决于它在闪存中的位置

GCC认为这是一个VLA是对的吗?

如何使用 VLA 语法使用 const 指针声明函数

创建 makefile 来编译位于不同目录中的多个源文件