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

Linux 实现后台进程

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



SIGHUP信号拦截

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

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

C++代码编写:

#include<iostream>
#include<unistd.h>
#include<signal.h>
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<iostream>
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
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<iostream>
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
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收留,这个进程的终端没了,它也会终止。


请添加图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux C/C++ 后台开发实践》是一本介绍在Linux环境下使用C/C++进行后台开发的实践指南。 该书主要分为以下几个部分: 第一部分是介绍Linux基础知识,包括Linux操作系统的原理、常用命令等。这部分的目的是为读者打下Linux基础,为后面的主题提供必要的背景知识。 第二部分是介绍C/C++语言的基础知识,包括语法、指针、内存管理等。这部分的目的是让读者熟悉C/C++语言的基本特性,为后续的后台开发做好准备。 第三部分是介绍Linux下的网络编程,包括Socket编程、网络通信协议等。这部分的目的是让读者了解网络编程的基本原理并能够使用C/C++进行网络通信。 第四部分是介绍多线程编程和进程通信,包括线程的创建与同步、进程间的通信机制等。这部分的目的是让读者了解多线程编程和进程通信的原理,并能够使用C/C++进行相关的开发。 第五部分是介绍常用的后台开发框架和技术,包括数据库访问、消息队列、Web服务等。这部分的目的是让读者了解后台开发中常用的框架和技术,并能够使用C/C++进行相关的开发。 通过阅读《Linux C/C++ 后台开发实践》,读者可以系统地了解并掌握在Linux环境下使用C/C++进行后台开发的基本技能。这本书的内容丰富、深入浅出,适合有一定编程基础的读者阅读,并可以作为后台开发工程师的参考书籍。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值