进程组、会话、守护进程

@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

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

感谢支持,长期连载

欢迎关注

相关推荐
比奥利奥还傲.1 小时前
哪吒监控面板实战:部署 Dashboard、接入 Agent、钉钉告警,再配置固定公网访问
网络·人工智能·分布式·1024程序员节
Mr YiRan7 小时前
网络请求API监控与网络切换埋点
android·网络
Shota Kishi7 小时前
Solana Shreds 的 UDP 直投架构:Shredstream UDP Forwarding 的设计与实现
网络协议·架构·udp·区块链·solana
当下新鲜事13 小时前
车间实测记录:三菱电机MR-J5伺服与压力控制方案的场景适配
网络·物联网·业界资讯
门思科技14 小时前
开源网关有哪些:主流类型梳理
网络·python·物联网
llilian_1615 小时前
北斗授时卡同步解决方案 gnss授时卡 计算机时间同步板卡
大数据·网络·人工智能·功能测试·51单片机
Vicky_time15 小时前
跨境物流系统架构:美国海外仓与FBA中转海外仓选型技术方案评测
网络·人工智能
玄芯散人15 小时前
【筑基·055】TCP vs UDP:可靠和快速的取舍
网络协议·tcpdump
多多鼠16 小时前
System Prompt 的“版本漂移”问题:从变更管理到 A/B 测试体系
开发语言·网络·人工智能·python·langchain
Allen_LVyingbo18 小时前
三甲医院医疗AI代码库管理系统研究(上)
网络·transformer·知识图谱·健康医疗