Linux守护进程运行命令daemonize

我们一般在编写服务器的时候都希望能让服务器在后台运行,而且能记录下这个服务器的pid,防止一个进程重复启动。之前我的方案是自己使用fork函数,将服务器运行成后台模式;并且在启动之前去检查配置文件中指定的pid文件中是否能读出pid信息,并且在当前的ps aux中查找这个pid的进程是否还活着。这样来判定服务器是否已经启动了。当正常启动完毕之后,将会把当前进程的pid写入文件。这样就能防止重复启动了。从刚刚的描述中可以看出其实大多的服务器程序可能需要有以下几个需求:

  1. 需要后台运行
  2. 需要记录pid方便今后服务器信息的读取
  3. 需要防止服务器被错误的重复启动

其实在Linux的基础设施中有这样类似的命令来处理:

$ daemonize

有了这个活宝,可以减少自己去学习Linux那套daemon方式的编程。在写程序的时候直接实现自己的服务器主流程即可。这种减少掉自己代码中的平台相关的东西还是比较好。能让代码更加清晰。

描述

daemonize可以将一个命令运行成Unix的后台。后台程序是不需要借助终端或者登陆的shell运行在服务器上的,并且等待一些时间的出现,或者等待去执行一些规定的任务在一定周期内。一个典型的后台程序江湖:

关闭全部文件描述字(除开标准输出、输出和错误输出)
将工作目录设置成文件系统的root目录,确保它没有挂载任何其他的文件系统,预防它被卸载
重设他的umask
运行在后台(fork)
分离处理组(通常是一个shell),隔绝掉信号(如挂起信号HUP);
忽略掉全部中断的I/O信号
从中断分离控制权
处理任何SIGCLD信号

选项

-a

挂载到输出文件,而不是冲掉默认值。只有应用了-e and/or -o 被指定的情况。

-e

重定向输出标准错误到指定的文件中,替代/dev/null

-o

重定向输出标准到指定的文件中,替代/dev/null

-E name=value

增加环境变量给给后台程序。这个这个参数类型一定要是name=value格式。参数可以设置多次。

-c directory

定制运行命令前的目录。

-p pidfile

定制自己的pid存放位置。

-l lockfile

单实例启动时将会检查这个文件。

-u user

定制程序以谁的身份运行的。

-v

将会触发daemonize将自己程序的运行详细的日志输出到标准输出中。

注意事项

如果宿主操作系统提供了daemon库程序,daemonize 将会使用它。否则 daemonize将使用自己实现的daemon。这个选择是在编译期做的。
FreeBSD 5.0引入了daemon命令类似于这个命令,但是没有提供如此多的功能。

关于

Brian M. Clapper, bmc@clapper.org
daemonize Home Page: http://software.clapper.org/daemonize/
August 2006

实例

##测试代码:

#include <iostream>
#include <thread>

int main( int argn, char *argv[] )
{
    int loop_count = 0;  
    while ( true ) {     
        loop_count ++;   
        if ( loop_count > 10 ) {  
            loop_count = 0;           
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        if ( loop_count == 5 ) {  
            std::cout << "is normalize output " << std::endl;
        }
        if ( loop_count == 9 ) {  
            std::cerr << "is error output" << std::endl;
        }
    }
    return 0;
}

##启动的shell

daemonize -a -e /home/abel/test_daemonize/error.log -o /home/abel/test_daemonize/output.log -p /home/abel/test_daemonize/daeminze.pid -l /home/ab    el/test_daemonize/lockfile /home/abel/test_daemonize/test_daemonize -c mycfg.cfg

文件列表

test_daemonize]$ ls
daeminze.pid  error.log  launch.sh  lockfile  main.cpp  main.o  output.log  SConstruct  test_daemonize

pid文件内容

$ cat ./daeminze.pid 
11520

日志文件

# output.log
is normalize output 
is normalize output
# error.log
is error output
is error output
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux 中,守护进程是一种运行在后台的进程,通常用于执行一些长期运行的任务,例如网络服务、定时任务等。下面是生成守护进程的大致步骤: 1. 创建一个子进程,并在子进程中调用 `setsid` 函数,以创建一个新的会话并成为该会话的首进程。 2. 在子进程中调用 `chdir` 函数,将工作目录切换到根目录以避免挂载文件系统时的问题。 3. 在子进程中关闭不需要的文件描述符,例如标准输入、标准输出、标准错误输出等。 4. 在子进程中执行守护进程的主逻辑,例如监听网络连接、处理客户端请求等。 5. 在父进程中退出,使得子进程成为孤儿进程,从而成为守护进程。 下面是一个简单的示例代码: ```c #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <fcntl.h> void daemonize() { // 创建子进程 pid_t pid = fork(); if (pid < 0) { perror("fork"); exit(1); } else if (pid > 0) { // 父进程退出 exit(0); } // 创建新会话并成为首进程 if (setsid() < 0) { perror("setsid"); exit(1); } // 切换工作目录 if (chdir("/") < 0) { perror("chdir"); exit(1); } // 关闭文件描述符 close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); // 执行守护进程主逻辑 while (1) { // do something } } int main() { // 生成守护进程 daemonize(); // 守护进程主逻辑 while (1) { // do something } return 0; } ``` 这个示例代码中,`daemonize` 函数用于生成守护进程。在函数中,首先调用 `fork` 函数创建子进程,然后在子进程中调用 `setsid` 函数创建一个新的会话并成为首进程。接下来,调用 `chdir` 函数将工作目录切换到根目录,调用 `close` 函数关闭不需要的文件描述符。最后,在子进程中执行守护进程的主逻辑。 在 `main` 函数中,首先调用 `daemonize` 函数生成守护进程,然后在主循环中执行守护进程的主逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值