gpt4 book ai didi

在 Linux 中创建守护进程

转载 作者:IT老高 更新时间:2023-10-28 12:24:27 24 4
gpt4 key购买 nike

在 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;
}

最佳答案

In Linux i want to add a daemon that cannot be stopped and which monitors filesystem changes. If any changes would be detected it should write the path to the console where it was started + a newline.

守护进程在后台工作并且(通常...)不属于 TTY,这就是为什么您不能以您可能想要的方式使用 stdout/stderr。通常使用 syslog 守护进程 (syslogd) 将消息记录到文件(调试、错误...)。

除此之外,还有一些必需的步骤来守护进程。


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

  • fork 关闭父进程,如果 fork 成功则让它终止。 -> 因为父进程已经终止,子进程现在在后台运行。
  • setsid - 创建一个新 session 。调用进程成为新 session 的领导者和新进程组的进程组领导者。该进程现在已与其控制终端 (CTTY) 分离。
  • 捕捉信号 - 忽略和/或处理信号。
  • 再次 fork 并让父进程终止以确保您摆脱 session 领导进程。 (只有 session 负责人可以再次获得 TTY。)
  • chdir - 更改守护程序的工作目录。
  • umask - 根据守护进程的需要更改文件模式掩码。
  • close - 关闭所有可能从父进程继承的打开文件描述符。

为您提供一个起点:查看显示基本步骤的框架代码。此代码现在也可以在 GitHub 上 fork :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 | ./  |+------+------+------+------+-----+-------+------+------+------+-----+

您应该在这里看到的是:

  • 守护进程没有控制终端 (TTY = ?)
  • 父进程 ID (PPID) 为 1(初始化进程)
  • PID != SID 表示我们的进程不是 session 负责人
    (因为第二个 fork())
  • 因为 PID != SID 我们的进程无法再次控制 TTY

阅读系统日志:

  • 找到您的系统日志文件。我的在这里:/var/log/syslog
  • 执行:grep firstdaemon/var/log/syslog

  • 输出应该和这个类似:

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


备注:实际上,您还希望实现一个信号处理程序并正确设置日志记录(文件、日志级别...)。

进一步阅读:

关于在 Linux 中创建守护进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17954432/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com