进程间关系和守护进程

别再为下载速度发愁了!手把手教你给qBittorrent/Transmission添加最新可用Tracker(附2024年实测地址清单) 本文提供2024年BT下载加速实战指南,详细解析Tracker工作原理与速度瓶颈,手把手教你为qBittorrent/Transmission添加最新可用Tracker,并附实测地址清单。通过优化配置和精选Tracker列表,显著提升下载速度和稳定性,解决连接延迟和peer数量限制问题。 阅读详情

一、进程组/作业/会话

1、进程组

1)每个进程除了有一个进程ID之外,还属于一个进程组,进程组是一个或多个进程的集合,通常,它们与同一作业相关联,可以接收来自同一终端的各种信号
2)每个进程有一个唯一的进程组ID。每个进程组可以有一个组长进程,组长进程的标识是,进程组ID等于其进程的ID。
3)组长进程可以创建一个进程组,创建该组中的进程。然后终止,只要在某个进程组中有一个进程存在,则该进程组就存在,这与组长进程是否终止无关,实例如下:
这里写图片描述

2、作业

1)shell分前后 台来控制的不是进程而是作业,或者进程组;
2)一个前台作业可以由多个进程组成,一个后台也可以由多个进程组成。shell可以运行一个前台程序和任意多个后台程序,这称为作业控制。
3)作业和进程组的区别在于:如果作业中的某个进程又创建了子进程,子进程不属于作业。而是属于进程组的。
4)一旦作业运行结束,shell就把自己提到了前台(子进程还在,可是子进程不属于作业),如果原来的前台进程还存在(如果这个子进程还没终止),它自动变为后台进程组。
5)我们重新理解一下,在前台新起作业,shell无法运行的,因为它被提到了后台。但是他被提到了后台,如果原来的前台进程退出,shell又被提到了后台,所以可以继续的接受用户的输入。
我们来看一个例子:

 1 #include <stdio.h>
  2 #include <unistd.h>
  3 
  4 int main(){
  5     pid_t id=fork();
  6     if(id<0){
  7         perror("fork");
  8         return 1;
  9     }
 10     else if(id==0){//child 
 11         while(1){
 12             printf("child(%d)# I am running !\n",getpid());
 13             sleep(1);
 14         }
 15     }
 16     else{//parent
 17         int i=5;
 18         while(i){
 19             printf("parent(%d)# I am going to dead...%d\n",getpid(),i--);
 20             sleep(1);
 21         }
 22     }
 23     return 0;
 24 }
 25 

结果展示:
这里写图片描述
我们在来接着上面的代码看下
这里写图片描述
我们看到的是子进程被提到前台执行shell命令,当我们执行kill -9 命令可以看到被打散了,但是换是能在前台进行识别,所以执行kill -9可以直接杀死子进程。

作业控制:

Semission和进程组一样“shell同时运行一个前台进程和任意多个后台进程”其实是不全面的,现在我们来研究更复杂的结构,事实上,shell分前后台来控制的不是进程而是作业或者进程组(Process Group),一个前台作业可以由多个进程组成,一个后台作业也可以由多个进程组成,shell可以同时运行一个前台作业和任意多个后台作业,,这称为作业控制。
这里写图片描述
作业控制有关的的信号
我们通过实验来理解与作业控制有关的信号
这里写图片描述
将cat放到后台运行,由于cat需要读标准输入(也就是终端输入),而后台进程是不能读终端输入的,因此内核发SIGTTIN信号给进程,该信号的默认处理动作是使进程停止。
这里写图片描述
1)如果该作业的进程组正在后台运行则提至前台运行,如果该作业处于停止状态,则给进程组的每个进程发SINCONT信号,可以使它继续运行。
2)参数4表示的是将作业4提到了前台运行,cat提到前台运行后,挂起等待终端输cat打印出哦同样的一行,然后继续挂起等待输入。
3)如果输入Ctrl + Z则向所有的前台进程发SIGTSTP信号,该信号的默认处理动作是使进程停止,cat继续以后台作业的形式存在。
4)bg命令可以让某个停止的动作在后台继续运行,也需要给该作业的进程组的每个进程进行发送SIGTTIN信号,cat进程继续运行,又要读终端输入,然而它在后台不能读终端输入,所以又收到SIGTTIN信号而停止。
这里写图片描述
用kill命令给一个停止的进程发SIGTERM(15)信号,这个信号并不会立即被处理,而是要等进程准备继续运行之前处理,默认动作是终止进程。但是如果给一个停止的进程发SIGKILL信号就不同了。
后台进程不能从终端下读取数据,但是能写吗?
答案: 可以。

3、会话(session)

1)会话是一个或多个进程组的集合,一个会话可以有一个控制终端。这通常是登陆到其上的终端设备(在终端登陆情况下)或伪终端设备(在网络登陆情况下),建立与控制终端连接的会话首进程被称为控制进程。
2)一个会话中的几个进程组可被分为一个前台进程组(通常是bash)以及一个或者多个后台进程组。
3)一个会话中应该包括控制进程(会话首进程),一个前台进程组和任意后台进程组。删除会话相当于注销。
这里写图片描述
注意:一般我们的在本地终端登陆的是bash,而网络登陆是-bash
这里写图片描述
这里写图片描述

4、了解终端

1.终端的基本概念
(1)Shell进程的控制终端 (Controlling Terminal):在UNIX系统中,用户通过终端登录系统后得到一个Shell进程。控制终端是保存在PCB中的信息,而我们知道fork会复制PCB中的信息,因此由Shell进程启动的其它进程的控制终端也是这个终端。默认情况下(没有重定向)。
每个进程的标准输入、标准输出和标准错误输出都指向控制终端,进程从标准输入读也就是读用户的键盘输入,进程往标准输出或标准错误输出写也就是输出到显示器上。另外,在控制终端输入一些特殊的控制键可以给前台进程发信号(例如Ctrl C表示SIGINT,Ctrl \表示SIGQUIT)。
2.每个进程都可以通过一个特殊的设备文件/dev/tty来访问它的控制终端。
ttyname函数可以由文件描述符查出对应的文件名,该文件描述符必须指向一个终端设备而不 能是任意文件。
查看终端对应的设备:

 1 #include <stdio.h>                                                                                                                                        
  2 #include <unistd.h>
  3 
  4 int main()
  5 {
  6     printf("fd:%d    ->   %s\n",0,ttyname(0));
  7     printf("fd:%d    ->   %s\n",1,ttyname(1));
  8     printf("fd:%d    ->   %s\n",2,ttyname(2));
  9     return 0;
 10 }
 11 

这里写图片描述

二、守护进程(Daemon)

认识守护进程
守护进程也称精灵进程(Daemon),是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程是一种很有用的进程。Linux的大多数服务器就是用守护进程实现的,比如ftp服务器,ssh服务器,Web服务器httpd等。同时,守护进程完成许多系统的任务。比如,作业规划进程crond等。
linux系统启动时会启动很多系统服务进程,这些系统服务进程没有控制终端,,不能直接和用户交互,其他进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但系统服务进程(守护进程)不受用户登录注销的影响,(因为它们自成会话,不在会话的范围内)它们一直运行着,这种进程叫做守护进程(Daemon)。
下面我们可以用ps axj命令查看系统中的进程。参数a表示不仅列当前用户的进程,也列出所有其他用户的进程,参数x表示不仅列有控制终端的进程,也列出所有无控制控端的进程,参数j表示的是列出与作业控制相关的信息。

ps axj | more
其中more与cat类似,在读取的时候是以按页读取,按空格键进行下一页
这里写图片描述

  • TPGID前台进程组ID,写着-1的都是没有控制终端的进程,也就是守护进程。
  • 在COMMAND一列用[ ]括起来的名字表示内核线程,这些线程在内核里创建,没有用户空间代码,因此没有程序文件名和命令行,通常采用以k开头的名字,表示Kernel。
  • udevd负责维护dev目录下的设备文件,acpid负责电源管理,syslogd负责维护/var/log下的日志文件。
  • 守护进程通常采用d结尾的名字,表示Daemon。
    创建守护进程
    创建守护进程最关键的一步是调用setsid函数创建一个新的Semssion,并成为Semssion leader。
setsid函数  
#include <unistd.h> 
pid_t setsid(void);    
该函数调用时返回新创建的Semssion的id(其实也就是当前进程的id)出错返回-1

注意:调用这个函数之前,当前进程不允许是进行组的leader’,否则会返回-1。要保证当前进程不是进程组的leader也很容易,只要先fork再调用setsid就行了。
fork创建的子进程和父进程同在一个进程组中,进程组的leader必然是第一个进程,所以子进程不可能是该组的第一个进程,在子进程中调用setsid就不会有问题了。
成功调用该函数的结果是:
- 创建一个新的Session,当前进程成为Session Leader,当前进程的id就是Session的id
- 创建一个新的进程组,当前进程成为进程组的Leader,当前进程的id就是进程组的id。
- 如果当前进程原本有一个控制终端,则它失去这个控制终端,成为一个没有控制终端的进程,所谓失去控制终端是指原来的控制终端仍然是打开的,仍然可以读写,但只是一个普通的打开的文件而不是控制终端了。
编写守护进程代码:
1)首先调用umask函数,将文件创建模式屏蔽字设置为已知值(通常为0)。
2)调用fork函数,使父进程exit,可以实现(a):父进程可以让shell认为该命令是执行完毕了。(b)守护进程调用库函数创建文件,可以将屏蔽字设置为一个更强的限制性的值,(如007)因为库函数可能不允许调用者通过一个显式的函数参数来设置权限。
3)调用seisid创建一个新会话。
4)将当前的工作目录改为根目录,从父进程处继承过来的当前工作目录可能在一个挂载文件系统中。因为守护进程通常在系统再引导之前是一直存在的。
5)关闭不再需要的文件描述符,这使守护进程不再持有从父进程继承而来的任何文件描述符。可以用open_max函数或getrlimit函数来判定最高文件描述符值,并关闭直到该值的所有的文件描述符。
6)某些守护进程打开/dev/null使具有文件描述符0、1和2,这样任何一个试图读标准输入、写标准输出或标准错误的库例程都不会产生任何效果。因为守护进程并不与终端设备相关联所以输出无处显示,,也无从从交互式用户那里接受输入。
daemon函数
这里写图片描述

nochdir:当此参数为0时,会更改创建出的danmon的执行目录为根目录,否则(非0)时保持当前执行目录不变。
noclose:当次函数为0时,会将标准输入(0),标准输出(1),标准错误(2)重定向到/dev/null,否则保持原有标准输入(0),标准输出(1),标准错误(2)不变。
代码实现:

 #include <stdio.h>
  2 #include <signal.h>
  3 #include <unistd.h>
  4 #include <stdlib.h>
  5 #include <fcntl.h>
  6 #include <sys/stat.h>
  7 
  8 void mydaemon(void)
  9 {
 10     int fd0;
 11     pid_t pid;
 12     struct sigaction sa;
 13     umask(0);//1、调用umask将文件模式创建屏蔽字设置为0
 14             //2、调用fork,父进程退出(exit),如果该守护进程是作为一条简单的shell命令进行启动的
 15             //那么父进程终止使得shell认为该命令已经执行完毕
 16             //保证子进程不是一个进程组的组长进程
 17     if((pid=fork()<0)){
 18                 perror("fork");
 19         }else if(pid>0){
 20             exit(0);//终止父进程
 21         }
 22     setsid();//3、创建一个新的会话
 23     sa.sa_handler=SIG_IGN;//4、忽略SIGCHID信号
 24     sigemptyset(&sa.sa_mask);
 25     sa.sa_flags=0;
 26 
 27     if(sigaction(SIGCHLD,&sa,NULL)<0){//注册子进程退出忽略信号,不要等待
 28     return ;
 29     }
 30     if(chdir("/")<0){//将当前目录更改为根目录
 31         printf("child dir error\n");
 32         return ;
 33     }
 34     //关闭文件描述符,或重定向到/dev/null
 35     close(0);
 36     fd0=open("/dev/null",O_RDWR);
 37     dup2(fd0,1);
 38     dup2(fd0,2);
 39 }
 40 
 41 
 42 int main()
 43 {
 44     mydaemon();
 45     while(1){
 46         sleep(1);
 47     }
 48 }
 49                                                                                                                                                                                                                                                                            
~                                                                                                                                                                                                                                                                              
~                           

这里写图片描述
这里写图片描述
这样我们就成功的创建出来了守护进程。

游戏大厂如何解析引擎技术 本文系统解析了游戏大厂如何评估和定制游戏引擎。游戏引擎作为游戏开发的核心基础,大厂会从性能、跨平台支持、渲染能力、网络模块等8个维度进行技术解析,通过文档查勘、源码阅读、Demo测试等7个步骤深度评估。解析后通常有三种决策:直接使用、深度定制或自研重构。文章以腾讯、网易、米哈游等为例,展示了不同厂商的引擎定制策略,并分析了技术解析面临的挑战和未来趋势。最终指出,体系化的引擎技术解析是打造高质量游戏的关键,需要持续的技术投入和团队协作。 阅读详情

相关推荐

深度残差网络的无人机多目标识别

深度残差网络的无人机多目标识别 人工智能技术与咨询 来源:《图学学报》。作者翟进有等 摘要:传统目标识别算法中,经典的区域建议网络(RPN)在提取目标候选区域时计算量大,时间复杂度较高,因此提出一种级联区域建议网络(CRPN)的搜索模式对其进行改善。此外,深层次的卷积神经网络训练中易产生退化现象,而引入残差学习的深度残差网络(ResNet),能够有效抑制该现象。对多种不同深度以及不同参数的网络模型进行研究,将两层残差学习模块与三层残差学习模块结合使用,设计出一种占用内存更小、时间复杂度更低的新型多捷.

m0_62870606的博客 3113

进程间关系

进程间的关系

风华绝代 2635

xhs私信协议分析

之前分析过xhs的shield算法,今天再聊聊xhs的私信,文章仅供学习参考研究交流,如有侵权请联系删帖。经过抓包分析发现私信接口并不是走的http协议,而是socket协议。而要获取socket包则需要使用wireshark软件1、protobuf的包体中的序号7,多次验证后发现文字信息的需要需要固定成12、protobuf的包体中的序号12,多次验证后发现文字信息的需要需要固定成1后续有时间的话,再研究一下视频和图片格式的私信协议,这次就分析到这里吧。

佛系更新... 3486

Linux-进程间关系与守护进程

守护进程(Daemon Process)是在Unix和类Unix操作系统(如Linux)中运行的一种特殊类型的进程。它们通常在系统启动时自动启动,并在后台运行,执行一些诸如监控或管理其他进程、系统服务、网络服务等任务。

m0_74910646的博客 1285

【Ultrascale+ MPSOC学习记录】10、PS端以太网使用lwip

还是参考ALINX教程,学习PS端以太网如何使用,从教程中可以看到,开发板使用了一个xilinx默认不支持的phy JL2121,所以需要修改lwip的库源码。

ryo891012的博客 881

18、近端策略优化(PPO)算法详解

本文详细介绍了近端策略优化(PPO)算法的理论基础、算法流程、实现方法及实际应用。PPO作为当前最受欢迎的策略梯度算法之一,具有易于实现、计算成本低、样本效率高和性能优越等优点。文章对比了基于自适应KL惩罚和基于裁剪目标的两种PPO变体,重点解析了裁剪目标函数的设计原理及其在Actor-Critic框架下的实现方式,并通过Atari Pong游戏展示了完整的训练配置与流程。最后总结了PPO的优势、适用场景及未来发展方向,为强化学习研究者和实践者提供了全面的参考。

mongodb5scout的博客 180

【C/C++】子进程与父进程关联与区别

当创建一个子进程时,子进程会进行拷贝部分父进程的部分数据。

Michael 1153

嵌入式软考必备知识点:嵌入式系统开发中的重要概念和示例代码

在嵌入式软考中,有一些重要的知识点需要掌握,包括嵌入式系统的基本概念、编程语言、实时操作系统和硬件接口等。实时操作系统是一种专门设计用于嵌入式系统的操作系统,可以提供对任务调度、中断处理和资源管理等方面的支持。GPIO(通用输入输出):GPIO是嵌入式系统中常用的硬件接口,用于连接外部设备和嵌入式系统。以上是嵌入式软考中的一些必备知识点,包括嵌入式系统的基本概念、编程语言、实时操作系统和硬件接口。通过配置串口的波特率、数据位数和校验位等参数,可以实现与其他设备的可靠通信。一、嵌入式系统的基本概念。

PixeGO的博客 314

零基础创建Windows守护进程,手把手教学。

二、打开新建的.txt文件并将如下代码进行填入,这段代码是一个批处理脚本,用于守护进程("SSCOM33")的运行,如果进程停止,它会自动重新启动。需要将下面两句代码保存为扩展名为.vbs的文件,然后和上述.bat放在同一目录下,双击运行。需要注意的是:本人守护的进程为“sscom33.exe”,文件目录为“F:\sscom33.exe”,根据自己需求进行更改。这两句代码是用于在 Windows 脚本宿主(WSH)环境中运行的,用于执行名为 "deamon.bat" 的批处理脚本。(名称为自己任意设定的)

Lzw_znc的博客 5638

INCA ProF文件解析

本博文从实际应用出发,介绍INCA prof文件的关键信息,通过实例,描述当得到一个刷写需求后,如何在不改变用户之前的使用习惯的前提下,满足原有的INCA刷写应用数据和标定程序的需求。 声明:本文不涉及项目名称,没有商业目的,纯属分享技术,乐享知识。

汽车电子软件领域知识分享 1万+

【2026最新版】PCL点云处理算法汇总(C++长期更新版)

PCL学习目录。博客长期更新,最近一次更新时间为:2026年10月4日。

点云侠的博客 63万+

Linux进程间关系和守护进程

Linux进程间关系和守护进程

Xpccccc的博客 1044

SAP GR(Group Reporting)合并报表内容及功能简介(五)-合并和抵消

随着合并和收购数量的显著增加,企业在全球经济中面临着诸多挑战。其中最常见的是法律实体与子公司之间缺乏透明度,导致无法以经济高效的方式对账法律实体与子公司之间的公司间交易,从而造成结算出现重大延迟。公司间匹配和对账功能允许用户在关账过程中进行早期分析,以避免公司间差异,并缩短关账时的延迟。公司间匹配和对账功能交易级别匹配和实时对账基于各种组织维度(如公司、利润中心和合并单位)的灵活建模自动差异解决。应用内通信和工作流。与公司间抵销集成。

weixin_43853754的博客 4400

【Linux专栏_5】Linux进程间关系和守护进程

可以看到当一开运行进程的时候,父进程延时5秒的,此时进程有自己的PPID、PID、PGID,由于是单进程所以是自己的PID,当5秒结束后,创建子进程,让父进程直接退出,此时该进程就变为了孤儿进程,被1号进程领养,但所属的进程组ID是不变的,还是第一个进程运行的PID,只是PID变为了子进程的PID了。总结就是:当多个进程在运行时候,他们有各自的PPID、PID,但是PGID是相同的,因为是一个进程组,并且规定进程组ID就是第一进程执行时的PID。一个作业可以包含一个进程或者是进程组,进程之间相互协调。

2301_78704584的博客 889

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Linux---进程间关系和守护进程

进程间关系 进程组 进程组是一个或多个进程的集合 每个进程除了有一个进程ID之外,还属于一个进程组 这些进程通常与同一作业相关联,可以接受来自同一终端的各种信号 每个进程组有唯一进程组ID,每个进程组可以有一个组长进程,其进程ID和进程组ID一致 组长进程可以创建一个进程组,创建该组中进程,然后终止 只要某个进程组中有一个进程存在,该进程组就存在,与组长进程是否终止无关 从进程组的创建到最后一个...

phonycat的博客 486

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

进程间关系和守护进程复习

进程间关系和守护进程 进程间关系 进程组 1.一个或多个进程的集合 2.可以接受终端的各种信号,信号发送给进程组就等于发送给进程组中所有的进程 3.每个进程组有一个唯一的进程组ID,组长进程的ID就是进程组的ID,进程组的创建从组长进程加入开始 4.进程组的消亡要等到组中所有的进程结束 5.kill -9 -进程组号 杀死进程组 6.自动接收终端信号的组成为前台进程组 7.除非是默...

TaoShiLei的博客 293

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Linux 进程间关系和守护进程

Linux 进程间关系和守护进程 进程间关系 1. 进程组 2. 作业 2.1 作业与进程组的区别 2.2 作业与Shell的联系 3. 会话 4. 作业控制 守护进程 1. 什么是守护进程? 2. 创建守护进程的两种方法 2.1 setsid函数 2.2 daemon函数 Linux 进程间关系和守护进程 进程间关系 1. 进程组 进程组是一个或多个...

NeverWA的博客 1万+

Linux:进程间关系和守护进程

进程间关系 几个基本概念 1、进程组 每个进程不仅有一个进程ID,还属于一个进程组。进程组是一个或者多个进程的集合。每个进程组拥有一个唯一的进程组ID。每个进程组可以有一个组长进程。组长进程的标识是,其进程组ID等于其进程ID。组长进程可以创建一个进程组,创建该组中的进程,然后终止。只要在某个进程组中一个进程存在,则改进程组就存在,这与其组长进程是否终止无关。 如上图,sleep了三个...

erwuhuoche的博客 387

Linux《进程间关系和守护进程》

本文介绍了进程组、会话和守护进程等概念,并展示了如何将网络计算器服务器程序改造为守护进程。主要内容包括:1. 进程组概念及组长进程的作用;2. 会话的组成和会话首进程;3. 控制终端与进程关系;4. 作业控制相关操作;5. 守护进程的实现原理,通过setsid函数创建独立会话;6. 详细实现了Dameon函数,包含工作目录切换和标准流处理;7. 将网络计算器服务器改造为守护进程后,即使关闭Xshell终端也能继续运行。最后指出可以通过系统提供的daemon函数简化守护进程创建过程。

mljy.博客 1548

Linux-----进程间关系和守护进程

在学习完进程之后,我们再来谈谈进程间关系 一个正在运行的程序(即进程)有着许多属性,经常用于进程控制的有:实际用户id,有效用户id,设置用户id、组id、进程id、进程组id、会话id。 在这里我们先介绍三个概念: 进程组 / 作业 / 会话 进程组 之前我们说过每个进程都有自己的进程ID,那么进程组是什么呢?其实每个进程除了有一个进程ID之外,还属于一个进程组。进程组是一...

Amber的博客 464
上一篇: 【进程间通信】——认识同步与互斥,了解生产者消费者原理。
下一篇: 信号的基本概念及产生
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值