C/C++ Linux网络编程9 - TCP服务器实现流程和独立运行

上篇文章:C/C++ Linux网络编程8 - epoll + ET Reactor TCP服务器-CSDN博客

代码仓库:橘子真甜 (yzc-YZC) - Gitee.com

我们的服务器如何保证在后台运行?并且xshell退出后,仍可以正常运行不退出?即可以长时间对外服务,不受xshell的登入/注销/退出的影响?

目录

[一. 会话/作业/进程组](#一. 会话/作业/进程组)

[二. 进程守护化setid](#二. 进程守护化setid)


一. 会话/作业/进程组

会话:我们启动xshell就是一个以bash为首的会话组。一个会话有一个前台进程组(有且只有一个)和若干后台进程组组成

进程组:由进程组成的集合,一个进程组用于完成一个作业

作业:设立了层的抽象,一个作业由一个进程组完成。大多数情况二者是一样的

相关命令与操作:

在执行命令的后面添加一个 &。表示这个进程组会在后台运行,并构成一个作业

jobs:用于查看当前shell有哪些作业

fg 作业编号:将该作业(进程组)放到前台运行

bg 作业编号:启动后台暂停的作业(进程组)

ctrl + z :将前台作业(进程组)放到后台并且暂停

通过这四个命令我们可以查看作业,并控制它们的运行和运行方式(前台/后台)

示例如下:

此时我们的服务器在后台运行,此时仍能正常运行

通过fg将其放到前台,此时是正常运行的

ctrl Z 放到后台并停止,此时客户端发送数据无法响应,因为停止了(注意此时系统内部仍会将来自网络的数据写入到网络缓冲区中

bg命令再次启动服务器

构建一个进程组实现一个简单作业:

如下图,它们的sid(会话组)是一样的!

二. 进程守护化setid

调用这个系统调用会将创建一个新的会话,并将自己设置为会话组组长。前提是调用这个进程不是一个会话组的组长

创建一个守护进程的流程:

1 需要屏蔽部分信号的影响,避免子进程/对端进程发送的信号导致服务器进程关闭

2 保证自己不是会话组组长,可以通过fork子进程,父进程退出,让子进程变为孤儿进程来保证这个进程不是会话组组长

3 setid将自己设置为会话组组长,脱离原会话组影响

4 再次fork,关闭父进程,只留下子进程,此时这个会话组组长没有了。不再受到其他终端的影响。

3 需要关闭或者重定向**标准输入/输出/错误文件描述符fd。**我们可以将所有的数据都重定向到系统文件 /dev/null黑洞文件中,写入这个文件的所有数据都会丢失,永远读取不到

代码如下:

复制代码
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <signal.h>
#include <fcntl.h>


// 设置该进程守护化
void daemonSelf(const char *workPath = "/")
{
    // 1.fork子进程,父进程退出,自己为孤儿进程(不是会话组组长)
    pid_t id = fork();
    if (id > 0)
        exit(0);

    // 2. setid将自己设置为新会话组长,这样不受之前会话组影响
    int n = setsid();
    if (n < 0)
    {
        perror("setid error\n");
        exit(errno);
    }

    // 3.再次fork保证该会话组没有组长,这样就不会受到其他终端影响
    id = fork();
    if (id > 0)
        exit(0);

    // 4.重定向标准输入/输出/错误,防止stdin/stdout/stderr异常
    int fd = open("/dev/null", O_WRONLY);
    if (fd < 0)
    {
        perror("open null error\n");
        exit(errno);
    }
    dup2(fd, 0);
    dup2(fd, 1);
    dup2(fd, 2);

    // 5. chdir更换工作目录
    chdir(workPath);
}

这样就实现了我们的进程守护化,退出后仍能响应。测试如下

至此,一个守护进程服务器就实现了

相关推荐
0vvv07 分钟前
删除wsl环境下的Ubuntu系统
linux·运维·ubuntu
@土豆11 分钟前
Ubuntu 22.04 运行 Filebeat 7.11.2 崩溃问题分析及解决文档
linux·数据库·ubuntu
C++ 老炮儿的技术栈25 分钟前
GCC编译时无法向/tmp 目录写入临时汇编文件,因为设备空间不足,解决
linux·运维·开发语言·汇编·c++·git·qt
橘颂TA32 分钟前
【笔试】算法的暴力美学——牛客 NC213140 :除2!
c++·算法·结构与算法
Agent产品评测局36 分钟前
企业数据处理自动化落地,抓取分析全流程实现方案 —— 2026企业级智能体选型与技术路径深度解析
运维·人工智能·ai·自动化
autumn200539 分钟前
Flutter 框架跨平台鸿蒙开发 - 历史人物对话
服务器·flutter·华为·harmonyos
爱莉希雅&&&1 小时前
linux中MySQL数据库备份恢复的四种方法(更新中)
linux·数据库·mysql·数据库备份·mysqldumper
wsoz1 小时前
Leetcode普通数组-day5、6
c++·算法·leetcode·数组
我科绝伦(Huanhuan Zhou)1 小时前
分享一个网络智能运维系统
运维·网络
鬼先生_sir1 小时前
Spring Cloud 微服务监控实战:SkyWalking + Prometheus+Grafana 全栈解决方案
运维·spring cloud·grafana·prometheus·skywalking