[C++]-Linux中创建Daemon程序

Posted 飞鹰技术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[C++]-Linux中创建Daemon程序相关的知识,希望对你有一定的参考价值。

守护进程后台进程编写守护进程forkdaemon

Linux中的守护进程(daemon进程)相当于Windows中的后台服务程序,一直运行于后台。

守护进程

Linux中,每一个与用户进行交流的界面称为终端,每一个从此终端允许的进程都会依附于此终端,因此这个终端也称为这些进程的控制终端;当控制终端被关闭时,相应的进程都会自动关闭。若不想让进程因终端的关闭或变化而受影响,就需要把进程变为守护进程。

守护进程(Daemon进程)是脱离于终端(避免进程在执行过程中的信息在任何终端上显示,且进程也不会被任何终端所产生的信息打断)且在后台运行的进程。

后台进程

有多个命令与后台进程有关:

  • &:放在命令后面,让命令在后台运行(但依然受终端控制,终端退出时也会退出);若有输出,依然会在终端中显示;

  • nohup:在系统后台不挂断地运行命令,退出终端不会影响程序的运行(输出会重定向到nohub.out文件中);但会阻挡当前输入,若要真正后台,需要与&一起使用;

查看当前作业(后台运行程序):

  • jobs:查看当前有多少后台运行命令(只能查看当前终端的);

  • Ctrl+z:将一个前台执行的命令放到后台,并处于暂停状态;

  • fg:把指定命令(作业号,jobs显示的),调到前台继续运行;

  • bg:将后台暂停的命令(作业号,jobs显示的),变为后台继续运行(相当于在命令后+&继续运行);

# cliTest是一个定时(1s)输出一条日志的,不间断程序
> ./cliTest & # 后台运行(但终端上一直显示输出),且终端退出时程序也退出

> nohup ./cliTest # 后台运行,会阻挡输入;但终端退出时程序会继续运行

> nohup ./cliTest > nohup.out & 2>&1 # 以后台方式运行,且输出(标准与错误)重定向到nohub;此方式相当于启动了一个后台守护进程

编写守护进程

常见的编写守护进程有fork与daemon两种方式。

fork

通过fork子进程,然后退出父进程的方式实现:

#include "logHelper.h"
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>

void testFork(){
    pid_t pid = fork();
    if(pid<0){
        LOG(ERROR)<<"Can't create subprocess";
        return;
    }else{
        if(pid!=0){ // parent
            exit(0);
        }
    }

    setsid();
    if(chdir("/")<0){
        LOG(ERROR)<<"Can't change dir";
        exit(-1);
    }

    int fd = open("/dev/null", O_RDWR);
    dup2(fd, STDIN_FILENO);
    dup2(fd, STDOUT_FILENO);
    dup2(fd, STDERR_FILENO);

    int count=0;
    while (1){
        sleep(1);
        LOG(INFO)<<++count<<" : testFork ...";
    }
}

实现流程说明:

  • fork成功后,父进程退出;

  • 子进程调用setsid(),来创建新的进程会话(并成为会话首进程),从而脱离和终端的关联;

  • 将当前工作目录切换到根目录:非必须,避免因进程使用当前目录,而影响目录操作(如卸载当前目录所在系统等);

  • 重定向输入输出到/dev/null,通过dup2把标准输入、输出重定向;

daemon

Linux中专门提供了一个系统函数daemon,用于创建守护进程:

int daemon(int nochdir, int noclose);
  • nochdir:为0表示改变当前目录为根目录,1不改变;

  • noclose:为0表示重定向输入、输出到/dev/null,1不重定向;

void testDaemon(){
    LOG(INFO)<<"testDaemon start";
    if(daemon(10) == -1){
        std::cout<<"error\n"<<std::endl;
        exit(-1);
    }

    LOG(INFO)<<"testDaemon after daemon";
    int count=0;
    while (true){
        sleep(1);
        LOG(INFO)<<++count<<" : testDaemon ...";
//        std::cout<<"testDaemon..."<<std::endl;
    }
}


以上是关于[C++]-Linux中创建Daemon程序的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Netbeans 中创建跨平台 C++ 应用程序?

如何在 c++ 中创建一个适用于 Windows 和 linux 的文件夹(目录)[重复]

在包含 make 文件的 Linux 中创建的 Visual Studio 2015 中编译 C++ 项目

如何在 C++ 中创建 RAW TCP/IP 数据包?

如何在linux中创建一个进程

使用 C++ 调用 C# 时无法在另一个应用程序域中创建对象