Linux-进程相关函数

文章目录

  • Linux-进程相关函数
    • 父子进程关系
    • 父子进程地址空间
    • getpid函数 获取本进程号
    • getppid函数 获取当前进程的进程的父进程号
    • getpgid函数 获取进程组号
    • 示例
    • fork函数 创建进程
    • 区分父子进程
    • exit函数 进程退出
    • wait函数 等待子进程退出
    • waitpid函数

Linux-进程相关函数

每个进程都由一个进程号来标识,其类型为 pid_t(整型),进程号的范围:0~32767。进程号总是唯一的,但进程号可以重用。当一个进程终止后,其进程号就可以再次使用。

进程号(PID)

标识进程的一个非负整型数。

父进程号(PPID)

任何进程( 除 init 进程)都是由另一个进程创建,该进程称为被创建进程的父进程,对应的进程号称为父进程号(PPID)。如,A 进程创建了 B 进程,A 的进程号就是 B 进程的父进程号。

进程组号(PGID)

进程组是一个或多个进程的集合。他们之间相互关联,进程组可以接收同一终端的各种信号,关联的进程有一个进程组号(PGID) 。这个过程有点类似于 QQ 群,组相当于 QQ 群,各个进程相当于各个好友,把各个好友都拉入这个 QQ 群里,主要是方便管理,特别是通知某些事时,只要在群里吼一声,所有人都收到,简单粗暴。但是,这个进程组号和 QQ 群号是有点区别的,默认的情况下,当前的进程号会当做当前的进程组号。

父子进程关系

使用 fork() 函数得到的子进程是父进程的一个复制品,它从父进程处继承了整个进程的地址空间:包括进程上下文(进程执行活动全过程的静态描述)、进程堆栈、打开的文件描述符、信号控制设定、进程优先级、进程组号等。

子进程所独有的只有它的进程号,计时器等(只有小量信息)。因此,使用 fork() 函数的代价是很大的。

在这里插入图片描述
简单来说, 一个进程调用 fork() 函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。

实际上,更准确来说,Linux 的 fork() 使用是通过写时拷贝 (copy- on-write) 实现。写时拷贝是一种可以推迟甚至避免拷贝数据的技术。内核此时并不复制整个进程的地址空间,而是让父子进程共享同一个地址空间。只用在需要写入的时候才会复制地址空间,从而使各个进行拥有各自的地址空间。也就是说,资源的复制是在需要写入的时候才会进行,在此之前,只有以只读方式共享。

注意:fork之后父子进程共享文件,fork产生的子进程与父进程相同的文件文件描述符指向相同的文件表,引用计数增加,共享文件文件偏移指针。

  • Linux 的 fork() 使用是通过写时拷贝 (copy- on-write),读时共享实现

父子进程地址空间

  • 父子进程各自的地址空间是独立的

getpid函数 获取本进程号

#include <sys/types.h>
#include <unistd.h>
​
pid_t getpid(void);
功能:获取本进程号(PID)
参数:无
返回值:本进程号

getppid函数 获取当前进程的进程的父进程号

#include <sys/types.h>
#include <unistd.h>
​
pid_t getppid(void);
功能:获取调用此函数的进程的父进程号(PPID)
参数:无
返回值:调用此函数的进程的父进程号(PPID)

getpgid函数 获取进程组号

#include <sys/types.h>
#include <unistd.h>
​
pid_t getpgid(pid_t pid);
功能:获取进程组号(PGID)
参数:pid:进程号
返回值:参数为 0 时返回当前进程组号,否则返回参数指定的进程的进程组号

示例

int main()
{pid_t pid, ppid, pgid;
​pid = getpid();printf("pid = %d\n", pid);
​ppid = getppid();printf("ppid = %d\n", ppid);
​pgid = getpgid(pid);printf("pgid = %d\n", pgid);return 0;
}

fork函数 创建进程

#include <sys/types.h>
#include <unistd.h>
​
pid_t fork(void);
功能:用于从一个已存在的进程中创建一个新进程,新进程称为子进程,原进程称为父进程。
参数:无
返回值:成功:子进程中返回 0,父进程中返回子进程 ID。pid_t,为整型。失败:返回-1。失败的两个主要原因是:1)当前的进程数已经达到了系统规定的上限,这时 errno 的值被设置为 EAGAIN。2)系统内存不足,这时 errno 的值被设置为 ENOMEM。

区分父子进程

int main()
{pid_t pid;pid = fork();if (pid < 0){   // 没有创建成功  perror("fork");return 0;}if (0 == pid){ // 子进程  while (1){printf("I am son\n");sleep(1);}}else if (pid > 0){ // 父进程  while (1){printf("I am father\n");sleep(1);}}return 0;
}

exit函数 进程退出

#include <stdlib.h>
void exit(int status);#include <unistd.h>
void _exit(int status);
功能:结束调用此函数的进程。
参数:status:返回给父进程的参数(低 8 位有效),至于这个参数是多少根据需要来填写。
返回值:无

exit() 和 _exit() 函数功能和用法是一样的,无非时所包含的头文件不一样,还有的区别就是:exit()属于标准库函数,exit()属于系统调用函数。

  • exit() 函数会处理后续的刷新缓冲区的动作
  • _exit() 是直接退出进程,不做任何的后续处理操作

在这里插入图片描述

wait函数 等待子进程退出

在每个进程退出的时候,内核释放该进程所有的资源、包括打开的文件、占用的内存等。但是仍然为其保留一定的信息,这些信息主要主要指进程控制块PCB的信息(包括进程号、退出状态、运行时间等)。

父进程可以通过调用wait或waitpid得到它的退出状态同时彻底清除掉这个进程。

wait() 和 waitpid() 函数的功能一样,区别在于,wait() 函数会阻塞,waitpid() 可以设置不阻塞,waitpid() 还可以指定等待哪个子进程结束。

注意:一次wait或waitpid调用只能清理一个子进程,清理多个子进程应使用循环。

#include <sys/types.h>
#include <sys/wait.h>
​
pid_t wait(int *status);
功能:等待任意一个子进程结束,如果任意一个子进程结束了,此函数会回收该子进程的资源。
参数:status : 进程退出时的状态信息。
返回值:成功:已经结束子进程的进程号失败: -1

调用 wait() 函数的进程会挂起(阻塞),直到它的一个子进程退出或收到一个不能被忽视的信号时才被唤醒(相当于继续往下执行)。

若调用进程没有子进程,该函数立即返回;若它的子进程已经结束,该函数同样会立即返回,并且会回收那个早已结束进程的资源。

所以,wait()函数的主要功能为回收已经结束子进程的资源。

如果参数 status 的值不是 NULL,wait() 就会把子进程退出时的状态取出并存入其中,这是一个整数值(int),指出了子进程是正常退出还是被非正常结束的。

这个退出信息在一个 int 中包含了多个字段,直接使用这个值是没有意义的,我们需要用宏定义取出其中的每个字段。

宏函数可分为如下三组:

  1. WIFEXITED(status)

为非0 → 进程正常结束

WEXITSTATUS(status)

如上宏为真,使用此宏 → 获取进程退出状态 (exit的参数)

  1. WIFSIGNALED(status)

为非0 → 进程异常终止

WTERMSIG(status)

如上宏为真,使用此宏 → 取得使进程终止的那个信号的编号。

  1. WIFSTOPPED(status)

为非0 → 进程处于暂停状态

WSTOPSIG(status)

如上宏为真,使用此宏 → 取得使进程暂停的那个信号的编号。

WIFCONTINUED(status)

为真 → 进程暂停后已经继续运行

waitpid函数

#include <sys/types.h>
#include <sys/wait.h>
​
pid_t waitpid(pid_t pid, int *status, int options);
功能:等待子进程终止,如果子进程终止了,此函数会回收子进程的资源。
​
参数:pid : 参数 pid 的值有以下几种类型:pid > 0  等待进程 ID 等于 pid 的子进程。pid = 0  等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid 不会等待它。pid = -1 等待任一子进程,此时 waitpid 和 wait 作用一样。pid < -1 等待指定进程组中的任何子进程,这个进程组的 ID 等于 pid 的绝对值。
​status : 进程退出时的状态信息。和 wait() 用法一样。
​options : options 提供了一些额外的选项来控制 waitpid()0:同 wait(),阻塞父进程,等待子进程退出。WNOHANG:没有任何已经结束的子进程,则立即返回。WUNTRACED:如果子进程暂停了则此函数马上返回,并且不予以理会子进程的结束状态。(由于涉及到一些跟踪调试方面的知识,加之极少用到)返回值:waitpid() 的返回值比 wait() 稍微复杂一些,一共有 3 种情况:1) 当正常返回的时候,waitpid() 返回收集到的已经回收子进程的进程号;2) 如果设置了选项 WNOHANG,而调用中 waitpid() 发现没有已退出的子进程可等待,则返回 03) 如果调用中出错,则返回-1,这时 errno 会被设置成相应的值以指示错误所在,如:当 pid 所对应的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid() 就会出错返回,这时 errno 被设置为 ECHILD;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/94463.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/94463.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据挖掘 6.1 其他降维方法(不是很重要)

6.1 Other dimensionality reduction methods 6.1 其他降维方法 其他降维方法前言问题答案流形3 降维大纲3.1 线性方法3.2 非线性方法3.2.1 流形学习方法&#xff08;Manifold Learning&#xff09;3.2.2 概率方法&#xff08;Probabilistic Approaches&#xff09;3.2.3 拓扑数…

Unity中的特殊文件夹

一.工程路径获取print(Application.dataPath);只用于游戏开发编辑器模式下&#xff0c;游戏发布后此路径就不存在了二.Resources 资源文件夹//路径获取: //一般不获取 //只能使用Resources相关API进行加载 //如果硬要获取 可以用工程路径拼接print(Application.dataPath "…

Seaborn数据可视化实战:Seaborn高级使用与性能优化教程

Seaborn最佳实践与技巧 学习目标 本课程将深入探讨Seaborn库的高级使用技巧&#xff0c;包括性能优化、常见问题解决方法等&#xff0c;旨在帮助学员掌握如何高效地使用Seaborn进行数据可视化&#xff0c;提升图表的美观度和信息传达效率。 相关知识点 Seaborn最佳实践与技巧 学…

分布式系统与单机系统的优劣势对比

近期有遇到一个本地部署的需求&#xff0c;他们希望用主备方案&#xff0c;这就涉及到了备用系统怎么收费的问题。我们是单机系统&#xff0c;其他友商是分布式系统&#xff0c;那20坐席的手拨需求到底是选单机系统好&#xff0c;还是选分布式系统好呢&#xff1f;了解了两者的…

深度学习:从手写数字识别案例认识pytorch框架

目录 一、PyTorch 核心优势与框架定位 二、实战基础&#xff1a;核心库与数据准备 1. 关键库导入与功能说明 2. MNIST 数据集加载与可视化 &#xff08;1&#xff09;数据集下载与封装 &#xff08;2&#xff09;数据集可视化&#xff08;可选&#xff09; 3. DataLoade…

二分|组合|旋转数组

lc1976dijk min_pathpq. min_wlcr187同lc1823.约瑟夫环class Solution { public:int iceBreakingGame(int num, int target) {int x0;for(int i2;i<num;i){x(xtarget)%i;} return x;} };lc2972计算数组中可移除的子数组数量先找最长递增前缀&#xff0c;再结合递增后缀…

【C语言16天强化训练】从基础入门到进阶:Day 10

&#x1f525;个人主页&#xff1a;艾莉丝努力练剑 ❄专栏传送门&#xff1a;《C语言》、《数据结构与算法》、C语言刷题12天IO强训、LeetCode代码强化刷题、洛谷刷题、C/C基础知识知识强化补充、C/C干货分享&学习过程记录 &#x1f349;学习方向&#xff1a;C/C方向学习者…

云计算与云原生技术探索

&#x1f31f; Hello&#xff0c;我是蒋星熠Jaxonic&#xff01; &#x1f308; 在浩瀚无垠的技术宇宙中&#xff0c;我是一名执着的星际旅人&#xff0c;用代码绘制探索的轨迹。 &#x1f680; 每一个算法都是我点燃的推进器&#xff0c;每一行代码都是我航行的星图。 &#x…

STM32之ADC详解

一、ADC概述 ADC&#xff08;模拟量转数字量转换器&#xff09;&#xff0c;在 STM32 开发中&#xff0c;利用 ADC 端口的电压数据&#xff0c;转换为对应的具体数字量数据内容。可通过 ADC 方式获取常用数据内容有&#xff1a; 光敏电阻、电池电量、油箱油量 ADC 转换…

深入理解计算机网络:从基础到应用的全面解析

标题&#xff1a;深入理解计算机网络&#xff1a;从基础到应用的全面解析 引言 计算机网络已经渗透到我们生活的方方面面。从家庭Wi-Fi到全球互联网&#xff0c;我们每天都在通过各种设备进行数据交换。本文将带领你走进计算机网络的世界&#xff0c;深入探讨网络的基础知识、常…

以结构/序列/功能之间的关系重新定义蛋白质语言模型的分类:李明辰博士详解蛋白质语言模型

上海交通大学第三届「AI for Bioengineering 暑期学校」于 2025 年 8 月 8—10 日正式开启。本次暑期学校汇聚了自全球 70 余所高校、 10 余所科研机构及 10 余家行业领军企业的 200 余位青年才俊、科研学者和产业代表&#xff0c;共同聚焦于人工智能&#xff08;AI&#xff09…

【大语言模型 15】因果掩码与注意力掩码实现:深度学习中的信息流控制艺术

【大语言模型 15】因果掩码与注意力掩码实现&#xff1a;深度学习中的信息流控制艺术 关键词&#xff1a;因果掩码、注意力掩码、下三角掩码、Padding掩码、序列建模、GPT解码器、BERT编码器、批量处理优化、自回归语言模型、信息流控制 摘要&#xff1a;在Transformer架构中&a…

大型电动化工程机械设备智能施工试验场的网络设计方案

随着工程机械设备逐步迈向智能化、电动化和无人化&#xff0c;传统施工试验场已经难以满足现代化施工设备的研发、测试和验证需求。为了适应这一趋势&#xff0c;建设一个基于高性能网络架构的大型智能施工试验场成为关键。本文将从网络架构、设备选型和功能实现等方面&#xf…

SPMI总线协议(一)

1、简单说明 系统电源管理接口( System Power Management Interface简称SPMI)是一种双线串行接口,用于连接片上系统(SoC)处理器系统的集成电源控制器(PC)与一个或多个电源管理集成电路(PMIC)电压调节系统。SPMI 使系统能够使用单个 SPMI 总线动态调整 SoC 内部电压域的…

数据存储的思考——从RocketMQ和Mysql的架构入手

数据存储是后台服务系统永远绕不开的知识 笔者希望能够从宏观的角度出发&#xff0c;思考数据存储系统的共性和设计方案&#xff0c;尝试从Mysql和RocketMQ的角度去思考谈谈系统存储架构的设计哲学 前置的知识 什么是RocketMQ、什么是Mysql&#xff0c;他们对于后端系统的主用…

MySQL 面试题系列(二)

目录1: SQL 中常见的 JOIN 类型有哪些&#xff1f;请分别说明其连接逻辑和适用场景。2: UNION 和 UNION ALL 有什么区别&#xff1f;它们各自的适用场景是什么&#xff1f;3: 什么是视图 (View)&#xff1f;它的作用和优缺点是什么&#xff1f;4: 什么是索引 (Index)&#xff1…

PostgreSQL诊断系列(2/6):锁问题排查全攻略——揪出“阻塞元凶”

&#x1f517; 接上一篇《PostgreSQL全方位体检指南》&#xff0c;今天我们深入数据库的“神经系统”——锁机制&#xff0c;解决最令人头疼的“卡顿”问题。 你是否经历过&#xff1a; 某个SQL执行着就不动了&#xff1f;应用界面卡在“加载中”&#xff1f;UPDATE 语句迟迟不…

crc16是什么算法

核心概念​CRC16​ 是一种循环冗余校验算法&#xff0c;属于哈希函数的一种。它的核心目的是检测数据的错误&#xff0c;通常用于数字网络和存储设备中&#xff0c;来验证数据在传输或存储后是否依然完整、无误。你可以把它想象成一个数据的“指纹”或“摘要”。发送方计算出一…

Day8--HOT100--160. 相交链表,206. 反转链表,234. 回文链表,876. 链表的中间结点

Day8–HOT100–160. 相交链表&#xff0c;206. 反转链表&#xff0c;234. 回文链表&#xff0c;876. 链表的中间结点 每日刷题系列。今天的题目是力扣HOT100题单。 链表题目。 160. 相交链表 思路【我】&#xff1a; 1&#xff0c;计算链表长度 2&#xff0c;令A为较短链&am…

Rust面试题及详细答案120道(58-65)-- 集合类型

《前后端面试题》专栏集合了前后端各个知识模块的面试题&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…