在Linux中,我想添加一个无法停止的守护进程,它监视文件系统的更改。如果检测到任何更改,它应该写入启动控制台的路径以及换行符。
我已经准备好了更改文件系统的代码,但是我不知道如何创建守护进程。
我的密码是:http://www.yolinux.com/TUTORIALS/ForkExecProcesses.html
叉子用完后怎么办?
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中创建无法终止的进程。根用户(uid=0)可以向进程发送信号,有两个信号无法捕获,SIGKILL=9,SIGSTOP=19。和其他信号(未捕获时)也可能导致进程终止。
您可能需要一个更通用的守护程序函数,在该函数中,您可以为您的程序/守护程序指定名称,以及运行程序的路径(可能是/或/tmp)。您可能还需要为stderr和stdout(可能还有使用stdin的控制路径)提供文件。
以下是必要的包括:
#include <stdio.h> //printf(3)
#include <stdlib.h> //exit(3)
#include <unistd.h> //fork(3), chdir(3), sysconf(3)
#include <signal.h> //signal(3)
#include <sys/stat.h> //umask(3)
#include <syslog.h> //syslog(3), openlog(3), closelog(3)
这是一个更一般的函数,
int
daemonize(char* name, char* path, char* outfile, char* errfile, char* infile )
{
if(!path) { path="/"; }
if(!name) { name="medaemon"; }
if(!infile) { infile="/dev/null"; }
if(!outfile) { outfile="/dev/null"; }
if(!errfile) { errfile="/dev/null"; }
//printf("%s %s %s %s\n",name,path,outfile,infile);
pid_t child;
//fork, detach from process group leader
if( (child=fork())<0 ) { //failed fork
fprintf(stderr,"error: failed fork\n");
exit(EXIT_FAILURE);
}
if (child>0) { //parent
exit(EXIT_SUCCESS);
}
if( setsid()<0 ) { //failed to become session leader
fprintf(stderr,"error: failed setsid\n");
exit(EXIT_FAILURE);
}
//catch/ignore signals
signal(SIGCHLD,SIG_IGN);
signal(SIGHUP,SIG_IGN);
//fork second time
if ( (child=fork())<0) { //failed fork
fprintf(stderr,"error: failed fork\n");
exit(EXIT_FAILURE);
}
if( child>0 ) { //parent
exit(EXIT_SUCCESS);
}
//new file permissions
umask(0);
//change to path directory
chdir(path);
//Close all open file descriptors
int fd;
for( fd=sysconf(_SC_OPEN_MAX); fd>0; --fd )
{
close(fd);
}
//reopen stdin, stdout, stderr
stdin=fopen(infile,"r"); //fd=0
stdout=fopen(outfile,"w+"); //fd=1
stderr=fopen(errfile,"w+"); //fd=2
//open syslog
openlog(name,LOG_PID,LOG_DAEMON);
return(0);
}
下面是一个示例程序,它成为一个守护进程,挂起,然后离开。
int
main()
{
int res;
int ttl=120;
int delay=5;
if( (res=daemonize("mydaemon","/tmp",NULL,NULL,NULL)) != 0 ) {
fprintf(stderr,"error: daemonize failed\n");
exit(EXIT_FAILURE);
}
while( ttl>0 ) {
//daemon code here
syslog(LOG_NOTICE,"daemon ttl %d",ttl);
sleep(delay);
ttl-=delay;
}
syslog(LOG_NOTICE,"daemon ttl expired");
closelog();
return(EXIT_SUCCESS);
}
注意,SIG_IGN表示捕捉并忽略信号。您可以构建一个可以记录信号接收的信号处理程序,并设置标志(例如指示正常关机的标志)。
man 7 daemon
详细介绍了如何创建daemon。我的答案只是摘录自本手册。
至少有两种类型的守护程序:
如果您对传统的SysV守护进程感兴趣,则应实现以下步骤:
/proc/self/fd
来实现,回退是从文件描述符3迭代到RLIMIT\u NOFILE
的getrlimit()
返回的值
请注意以下警告:
不应该使用BSDdaemon()
函数,因为它只实现了这些步骤的子集。
需要提供与SysV系统兼容性的守护进程应该实现上述方案。但是,建议通过命令行参数使这种行为成为可选的和可配置的,以便于调试,并简化使用system d集成到系统中的过程。
请注意,daemon()
与POSIX不兼容。
对于新型守护进程,建议执行以下步骤:
SIGTERM
,请关闭守护进程并干净地退出
SIGHUP
,则重新加载配置文件(如果适用)
systemd。服务(5)
了解详细信息
systemd。exec(5)
,查看可用控件
sd\u notify(3)
接口通知init系统启动完成或状态更新
fprintf()
直接记录到标准错误,而不是使用syslog()
调用直接记录到系统syslog服务,然后由init系统转发到syslog。如果日志级别是必需的,可以通过在单个日志行前面加上字符串(如“0”)对其进行编码要了解更多信息,请阅读全文man7守护进程
。
在Linux中,我想添加一个无法停止的守护进程,它监视文件系统的更改。如果检测到任何更改,它应该将启动该更改的控制台的路径写入换行符。
守护进程在后台工作(通常...)不属于TTY,这就是为什么你不能以你可能想要的方式使用stdout/stderr。通常使用syslog守护进程(syromd)将消息记录到文件中(debug,错误,...)。
除此之外,还需要几个步骤来对流程进行后台监控。
如果我没记错的话,这些步骤是:
给你一个起点:看看这个显示基本步骤的框架代码。这段代码现在也可以在GitHub上分叉: linux守护进程的基本框架
/*
* 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 | ./ | +------+------+------+------+-----+-------+------+------+------+-----+
您应该在这里看到:
正在读取系统日志:
>
输出应类似于此:
firstdaemon[3387]: First daemon started. firstdaemon[3387]: First daemon terminated.
注意:实际上,您还需要实现一个信号处理程序并正确设置日志记录(文件、日志级别…)。
进一步阅读:
问题内容: 在Linux中,我想添加一个无法停止且监视文件系统更改的守护程序。如果检测到任何更改,则应在启动控制台的路径上加上换行符。 我已经准备好更改代码的文件系统了,但是我不知道如何创建守护程序。 我的代码来自这里:http : //www.yolinux.com/TUTORIALS/ForkExecProcesses.html 叉后该怎么办? 问题答案: 在Linux中,我想添加一个无法停止
问题内容: 我正在编写Linux守护程序。我发现了两种方法。 通过调用和设置守护进程。 使用运行程序。 哪个是正确的方法? 问题答案: 来自http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC16 以下是成为守护程序的步骤: 1. fork(),以便父级可以退出,这会将控制权返回给命令行或shell来调用您的程序。需要执行此步骤,以确保新流程不
问题内容: 这里有人在Golang中编写了守护进程吗?你能指导我如何做吗?欢迎有用的链接。 问题答案: 是的,这已经完成。请参阅go-daemon项目。请注意,启动goroutine 后 在守护进程中发生某些问题。有关详细信息,请参见问题227。 目前,我建议您使用操作系统提供的实用程序。
本文向大家介绍linux下的守护进程,包括了linux下的守护进程的使用技巧和注意事项,需要的朋友参考一下 Linux下的常驻进程的作用不可忽略,但这里面的问题也不能忽略,怎么启动进程,怎么结束进程,怎么在进程挂掉之后重启进程都要设计的合理。下面看一个shell控制的php常驻进程的例子。 不废话,直接捞干货,上代码,通过代码来讲解更容易理解: 只里面有几个要强调的地方: 我用这个shell去调用
问题内容: 在Google上搜索会发现x2代码段。第一个结果是该代码配方的内容,其中包含大量文档和说明,并在下面进行了一些有用的讨论。 但是,另一个代码示例虽然没有包含太多文档,但包含用于传递命令(例如启动,停止和重新启动)的示例代码。它还会创建一个PID文件,可以方便地检查守护程序是否已在运行等。 这些示例都说明了如何创建守护程序。还有其他需要考虑的事情吗?一个样本比另一个样本好吗,为什么? 问
问题内容: 创建可在Linux上使用“服务”运行的Java应用程序的最佳方法是什么?我打算使用此处提供的JSW ,但不能在此上使用许可证(许可证是GPL或据我所知要花钱)。我需要apache样式许可。 我正在使用maven进行构建,因此,如果可以使用maven插件创建服务,那就太好了,但是其他建议也都很棒。 我已经看过Apache Commons Daemon ,是否为此有一个Maven插件?文档