进程组、会话、守护进程

@bit::Shadow
✧(≖ ◡ ≖✿

目录

进程组

进程组的分类

sleep的后台运行举例

进程组VS任务

组长进程

会话

会话、任务、进程组辨识

常用指令

[jobs 的使用](#jobs 的使用)

[bg 的使用](#bg 的使用)

守护进程(精灵进程)

守护进程VS后台进程VS前台进程

代码创建

信号忽略

工作路径、日志系统

模拟实现守护进程

设备文件:/dev/null


进程组

进程组是以一个/多个进程为单位的多/单进程载体。

进程组ID(PGID)若进程组ID相同代表它们是属于一个进程组。

像自定义协议服务中一个服务端,多个客户端就是一个进程组。

进程组的分类

每个会话内只有两种进程组类型:前台进程组、后台进程组。

前台进程组:可以接受键盘输入的进程组(任务)。(像shell登录时创建的含-bash进程的进程组)

【shell启动进程组查询图】

后台进程组:即在后台运行的进程组(通过ps ajx查询),不接受键盘指令。(运行方式:./a.out &)在运行指令后加上"&"符号。

sleep的后台运行举例

运行如下指令指在后台进程组运行

bash 复制代码
sleep 1000 | sleep 2000 | sleep 3000 &

进程组VS任务

进程组是操作系统层面的概念而任务是用户层面的概念。

(本问题:具备混淆性,难以区分。)

组长进程

PGID与PID相同的进程为组长进程。(最多一个)

进程组的生命周期:子进程组创建开始到组内最后一个进程离开为止。

组长进程的作用:代表整个进程组接受信号(接收到后分发给组员)。获取控制终端,设置前台进程组:

{

tcsetpgrp(fd, pgid); // 将进程组设为前台

}

会话

会话、任务、进程组辨识

一个会话内可以可以有多个进程组。

会话也有自己的ID叫做"SID"。

图示关系

一个会话中可以有多个进程组,但只有一个前台进程组,可以有多个后台进程组。

常用指令

jobs 显示后台任务列表。

fg 任务号 将后台任务提到前台。

Ctrl + c 终止前台任务。(资源回收)

Ctrl + z 暂停 进程/进程组,自动切换到后台。

bg 任务号 让任务运行在后台。

jobs 的使用

bash 复制代码
[ubuntu@localhost ~]$ jobs
[1]  Running                 sleep 100 &
[2]  Running                 tail -f server.log
[3]+ Stopped                 vim CMakeLists.txt
[4]- Running                 ./serverTCP 8080
[5]  Done                    ls -l | grep txt
[6]  Stopped                 nano .gitignore

bg 的使用

bash 复制代码
# 1. 启动一个前台任务
$ sleep 300

# 2. 按 Ctrl+Z 暂停它
^Z
[1]+  Stopped                 sleep 300

# 3. 使用 bg 让它在后台继续运行
$ bg %1
[1]+ sleep 300 &

# 4. 现在这个任务在后台运行,你可以继续输入其他命令
$

守护进程(精灵进程)

解决目标:目前我们创建的程序++受用户登录/退出影响++,像启动的计算服务一旦xshell关闭客户端使用必定失效。为解决用户状态导致的服务端终止因此产生了精灵进程

定义:将需要不断运行的(不受用户登录、退出的影响的)进程(组)开辟至一新会话中,此会话就不会受用户的影响了。(在后台运行)

守护进程具有:"独立性" "孤儿性" 。

守护进程VS后台进程VS前台进程

后台、前台进程是隶属于一个会话的相对概念(的进程组)。

代码创建

为当前进程++创建一个新的会话++ ,并将当前进程PID设置为新会话ID(SID)。

cpp 复制代码
#include<unistd.h>
pid_t setsid();

注意:
1.
调用setsid()的进程不能为组长进程 (否则报错)。(因此我们常采用夫父进程直接退出,子进程创建新会话的操作)

**2.****守护进程无控制终端。**如果存在在调用后会切断。

信号忽略

常设置信号忽略SIGCHLD与SIDPIPE。

设置 SIGCHLDSIG_IGN,子进程会自动被回收,不会产生僵尸进程。

当进程向一个已关闭socket 写入数据时,内核 会发送SIGPIPE信号到写入进程导致服务端崩溃!!

工作路径、日志系统

工作路径:指进程组运行的根路径。(常切换(chdir)到根目录"/")

1.所有路径索引均基于工作路径!!!

2.此外还会影响编译时文件的链接。

日志系统基于工作路径的索引文件,将日志写入。(open dup2() close)

模拟实现守护进程

cpp 复制代码
/*守护进程译作:daemon (dei men)*/
const char *workpath = "/";
void Daemon (int cdir, int noclose)
{
    //解决IO问题
    signal (SIGCHLD, SIG_IGN);
    signal (SIGPIPE, SIG_IGN);

    if (fork () > 0)
        exit (0);
    //子进程创建作为新会话组组长
    pid_t ret = setsid ();
    if(ret < 0)
        RETFATAL ("setsid");

    //工作路径是否切换?(即守护进程运行的路径)
    if(cdir == 0)
        chdir (workpath);
    // 重定向标准输入、标准输出、标准错误到my.log文件(日志文件)
    // 这样做的要求是守护进程特征(默认关闭终端)
    if(noclose == 0)
    {
        int fd = open ("/my.log", O_RDWR);//读写
        if(fd < 0)
            RETFATAL ("open");
        int ret1 = dup2 (fd, 0);
        int ret2 = dup2 (fd, 1);
        int ret3 = dup2 (fd, 2);
        if(ret1 < 0 || ret2 < 0 || ret3 < 0)
            RETFATAL ("dup2");
        
        //打开的fd需要关闭吗?--->关闭后会影响写入吗?不会!!!
        // int ret4 = close (fd);
        // if(ret4 < 0)
        //     RETFATAL ("close");
    }
}

极其容易混淆的点:int dup2(int oldfd, int newfd); 此处是将newfd的指向重定向到oldfd。(而非旧到新)

设备文件:/dev/null

文件黑洞,文件垃圾箱。写入的内容全部丢弃,读取的内容全部为空。

感谢支持,长期连载

欢迎关注

相关推荐
严谨的麻辣烫17 分钟前
批量静态 IP 如何管理?用 Python 建立一个简单的 IP 资源监控方案
运维·服务器·网络·python·tcp/ip
wjcroom20 分钟前
在PVE中的直通和共享文件访问
网络·经验分享·虚拟化
MC皮蛋侠客10 小时前
DNP3 系列(十二):测试与工具链——模拟器、Wireshark 与一致性测试
网络·wireshark·dnp3
虎王物联10 小时前
工业Modbus TCP协议深度实战:STM32 HAL库实现从机通信与数据上云
stm32·物联网·网络协议·tcp/ip·嵌入式
观测云12 小时前
Fastjson 高危 RCE(CVE-2026-16723):如何用观测云快速发现并完成修复
网络·安全·可观测性·观测云
++==13 小时前
RESTful详解:核心思想、框架、与HTTP的区别,API的设计风格
后端·http·restful
楷哥爱开发14 小时前
TikTok Shop新加坡本土店入驻:如何选择新加坡本土住宅IP?
网络·网络协议·tcp/ip
网安蟹佬霸14 小时前
# 网络流量分析实战:从Wireshark到入侵检测系统构建(2026最新版,附完整流量分析链与IDS规则集)
网络·测试工具·安全·开源·wireshark·密码学·哈希算法
昌原的儿子LEO16 小时前
进程和线程(2)
linux·服务器·网络