栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Linux C++ 通信 -实现后台进程

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux C++ 通信 -实现后台进程

Linux 实现后台进程

每次终端关闭时,它的所有子进程也会因此而终止,显然,这是无法在实际运用中忽略的问题,此时,就需要把持续活动的进程移至后台运行。


目录
  • Linux 实现后台进程
    • SIGHUP信号拦截
    • 使用setsid函数
    • 使用setsid命令
    • 使用nohup命令
    • 后台执行


SIGHUP信号拦截

在Linux中,大多数进程的状态与它收到的信号有关。
其中,SIGHUP信号作用是连接断开后终止某个进程,即当一个终端被断开时,它的所有子进程都会收到SIGHUP信号,从而终止这些进程,所以可以想办法拦截这个信号,使目标进程无法收到SIGHUP信号而在后台运行。

准备一个死循环的C++文件,在Ubuntu中 通过g++编译成可执行文件,ssh连接到Ubuntu服务器,然后正常执行文件后,直接断开ssh连接,打开新的终端并搜索有无这文件的进程。

C++代码编写:

#include
#include
#include
using namespace std;

int main() {
    cout << "Linux C++" << endl;
	
	//拦截SIGHUP信号
    signal(SIGHUP, SIG_IGN); 

    while (1){
        sleep(1);
        cout << "terminal and bash Process" << endl;
    }

    cout << "end!" << endl;
    return 0;
}

编译:

# 执行完下述直接关闭终端
g++ -o t141 /mnt/hgfs/c/t141.cpp
./t141

结果:

# 新终端查看进程状态
ps -eo pid,ppid,sid,tty,pgrp,comm,stat | grep -E 'bash|PID|t141'

可以发现,t141仍在运行(STAT为S),由于它的终端被关闭了,TT变成了?,而且PPID变成了1,也就是说,这个进程现在被进程init收留了,是一个孤儿进程。

验证完毕,确认可行,可以执行kill -9 7650 杀死这个进程

使用setsid函数

该命令用于启动一个进程,而且能够使启动的进程在一个新的session(会话)中,这样终端关闭时进程就不会退出。

大佬fork的理解:fork

修改之前的C++文件:

#include
#include
#include
#include
using namespace std;

int main() {
    pid_t pid;
    cout << "Linux C++" << endl;

    pid = fork();  //系统函数,用来创建新进程,即创建主进程的子进程

    if ( pid < 0 ){
        cout << "fork进程出错" << endl;
    }else if ( pid == 0 ){

        cout << "子进程开始执行" << endl;

        setsid();  //创建新session
        while (1){
            sleep(1);
            cout << "子进程" << endl;
        }
        return 0;

    }else{
    	//父进程执行
        while (1){
            sleep(1);
            cout << "父进程" << endl;
        }
        return 0;
    }

    cout << "end!" << endl;
    return 0;
}

编译:

g++ -o t141 /mnt/hgfs/c/t141.cpp

执行 ./t141:

可以发现,父进程和子进程是同时运行的,相当于两个进程。
终止主进程后,可以发现子进程还在跑:

关闭终端后,这个子进程已经被init收留了,且STAT显示Ss,说明还在运行中:

kill掉这个子进程,sudo kill -9 34039

使用setsid命令

有没有什么其它方法能做到终端退出,启动的进程不关闭的呢?
可以使用setsid命令。setsid不但是个函数,其实它也是一个命令。该命令用于启动一个进程,而且能够使启动的进程在一个新的session中,这样终端关闭时进程就不会退出。

修改C++文件为:

#include
#include
#include
#include
using namespace std;

int main() {
    pid_t pid;
    cout << "Linux C++" << endl;

    while (1){
        sleep(1);
        cout << "子进程" << endl;
    }

    cout << "end!" << endl;
    return 0;
}

执行:

setsid ./t141

可以发现,跟使用了setsid函数一个结局,终止主进程之后,作为子进程的它还在跑:


依旧被init进程收留,而且运行着:


一样kill了

使用nohup命令

直接执行:

qiye@ubuntu:~/Desktop$ nohup ./t141 
nohup: ignoring input and appending output to 'nohup.out'


关闭终端后,在新终端查看:

再次被init收留,kill了

后台执行

在执行程序末尾增加一个“&”, 即输入:

./t141 &


它不会被进程init收留,这个进程的终端没了,它也会终止。


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1001666.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号