Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在Linux中创建守护进程_C_Linux_Daemon - Fatal编程技术网

C 在Linux中创建守护进程

C 在Linux中创建守护进程,c,linux,daemon,C,Linux,Daemon,在Linux中,我想添加一个无法停止的守护进程,它监视文件系统的更改。 如果检测到任何更改,它应该写入启动控制台的路径以及换行符 我已经准备好了更改文件系统的代码,但是我不知道如何创建守护进程 我的代码来自这里: 叉子用完后怎么办 int main (int argc, char **argv) { pid_t pID = fork(); if (pID == 0) { // child // Code only executed by

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

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

我的代码来自这里:

叉子用完后怎么办

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;
}
int main(int argc,char**argv){
pid_t pid=fork();
如果(pID==0){//child
//代码仅由子进程执行
sIdentifier=“子进程:”;
}
否则如果(pID<0){

cerr守护进程只是后台的一个进程。如果要在操作系统启动时启动程序,在linux上,可以将start命令添加到/etc/rc.d/rc.local(在所有其他脚本之后运行)或/etc/startup.sh

在windows上,您创建一个服务,注册该服务,然后在管理->服务面板中将其设置为在启动时自动启动。

通过调用fork(),您已经创建了一个子进程。如果fork成功(fork返回非零PID)执行将从此点在子进程内继续。在这种情况下,我们希望优雅地退出父进程,然后在子进程中继续我们的工作

也许这会有帮助:

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

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

除此之外,还需要几个步骤来对流程进行后台监控


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

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

给你一个起点:看看这个显示基本步骤的框架代码。这个代码现在也可以在GitHub上分叉:

/*
*daemonize.c
*此示例对进程进行后台监控,写入一些日志消息,
*睡眠20秒,然后结束。
*/
#包括
#包括
#包括
#包括
#包括
#包括
#包括
静态void骨架_守护进程()
{
pid_t pid;
/*离开父进程*/
pid=fork();
/*发生了一个错误*/
if(pid<0)
退出(退出失败);
/*成功:让父级终止*/
如果(pid>0)
退出(退出成功);
/*成功时:子进程成为会话负责人*/
if(setsid()<0)
退出(退出失败);
/*捕捉、忽略和处理信号*/
//TODO:实现一个工作信号处理程序*/
信号(信号灯、信号灯);
信号(信号灯、信号灯);
/*第二次出发*/
pid=fork();
/*发生了一个错误*/
if(pid<0)
退出(退出失败);
/*成功:让父级终止*/
如果(pid>0)
退出(退出成功);
/*设置新文件权限*/
乌马斯克(0);
/*将工作目录更改为根目录*/
/*或另一个适当的目录*/
chdir(“/”);
/*关闭所有打开的文件描述符*/
int x;
对于(x=sysconf(\u SC\u OPEN\u MAX);x>=0;x--)
{
关闭(x);
}
/*打开日志文件*/
openlog(“firstdaemon”,LOG\u-PID,LOG\u-DAEMON);
}
intmain()
{
骨架_守护进程();
而(1)
{
//TODO:在此处插入守护程序代码。
syslog(LOG_注意,“第一个守护进程已启动”);
睡眠(20);
打破
}
syslog(LOG_通知,“第一个守护进程终止”);
closelog();
返回退出成功;
}

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

  • 输出应与此类似:


注意事项: 实际上,您还需要实现一个信号处理程序并正确设置日志记录(文件、日志级别…)

进一步阅读:


我可以根据第一个要求停止“无法停止的守护进程”

我的朋友,这是不可能的;但是,你可以用一个更好的工具,一个内核模块来实现同样的目标


所有守护程序都可以停止。有些守护程序比其他守护程序更容易停止。即使是一对处于按住状态的守护程序,如果丢失,也可以重新保护该伙伴。您只需稍微努力一点即可。

您无法在linux中创建无法终止的进程。根用户(uid=0)可以向进程发送信号,有两个信号无法捕获,SIGKILL=9,SIGSTOP=19。其他信号(未捕获时)也可能导致进程终止

您可能需要一个更通用的daemonize函数,可以在其中为您指定一个名称 +------+------+------+------+-----+-------+------+------+------+-----+ | 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.
#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);
}
#include <unistd.h>

int daemon(int nochdir, int noclose);
{
  ".sh": "bash",
  ".py": "python",
  ".rb": "ruby",
  ".coffee" : "coffee",
  ".php": "php",
  ".pl" : "perl",
  ".js" : "node"
}
npm install -g pm2

pm2 start yourapp.yourext --name "fred" # where .yourext is one of the above

pm2 start yourapp.yourext -i 0 --name "fred" # run your app on all cores

pm2 list
pm2 startup

pm2 save
service pm2 stop|restart|start|status
[Unit]
Description=Simple daemon template
After=network.taget

[Service]
Type=simple
ExecStart=/usr/bin/daemon-template --conf_file /etc/daemon-template/daemon-tenplate.conf
ExecReload=/bin/kill -HUP $MAINPID
User=root
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=daemon-template

[Install]
WantedBy=multi-user.target