Linux 进程控制
文章目录
- 进程创建
- 进程终止
- 进程结果
- wait函数
- waitpid函数
- status参数
- 进程替换
- 进程替换原理
- 进程替换函数
- 补充/拓展
进程创建
- fork函数
#include <unistd.h>pid_t fork(void);
函数返回值:
在父进程中,fork函数返回子进程的进程ID(PID)
在子进程中,fork函数返回0。
fork执行失败时返回-1. fork 执行失败的原因一般是系统资源不足。
fork函数的一般使用逻辑:
int main() {pid_t pid = fork();if (pid < 0) {// fork失败,创建子进程失败fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程执行的代码逻辑printf("This is the child process\n");// 子进程执行其他任务...} else {// 父进程执行的代码逻辑printf("This is the parent process, child PID: %d\n", pid);// 父进程执行其他任务...}return 0;
}
内核视角:
分配新的内存块和内核数据结构给子进程
将父进程部分数据结构内容拷贝至子进程
添加子进程到系统进程列表当中
fork返回,开始调度器调度
进程终止
进程终止的原因:
- main函数返回
return n**等同于执行exit(n**),因为调用main的运行时函数会将main的返回值当做 exit的参数。
- exit函数返回
- _exit函数返沪
#include <unistd.h>void _exit(int status);
status 定义了进程的终止状态,父进程通过wait来获取该值
虽然status是int,但是仅有低8位可以被父进程所用。所以_exit(-1)时,在终端执行$?发现返回值
是255。
- 信号终止
_exit函数和exit函数说明:
- _exit函数
_exit函数是一个系统调用函数,用于立即终止程序的执行,不会执行任何清理工作,包括关闭文件、释放内存等。
它的原型为:void _exit(int status)。
status参数表示程序的终止状态,通常0表示正常终止,非零值表示异常终止。
_exit函数不会刷新缓冲区,也不会调用任何终止处理程序,直接退出程序。
- exit函数:
exit函数是标准库函数,用于终止程序的执行,并执行一些清理工作,如关闭文件、释放内存等。
它的原型为:void exit(int status)。
status参数表示程序的终止状态,通常0表示正常终止,非零值表示异常终止。
exit函数会先刷新缓冲区,然后调用终止处理程序(通过atexit注册的函数),最后退出程序。

进程结果
获取进程结果的方法
- 命令获取
echo $?
$?是一个特殊变量,用于获取上一个命令的退出状态码。退出状态码是一个整数值,表示上一个命令的执行结果。
- 父进程进程调用函数等待
wait函数
#include <sys/types.h>
#include <sys/wait.h>pid_t wait(int *status);
参数:
status是一个指向整型变量的指针,用于存储子进程的退出状态。
如果不关心子进程的退出状态,可以将status设置为NULL。
返回值:
wait()函数的返回值是子进程的进程ID,如果出错则返回-1。
如果当前进程没有子进程,返回-1,并设置errno为ECHILD
如果调用被信号中断,返回-1,并设置errno为EINTR
waitpid函数
#include <sys/types.h>
#include <sys/wait.h>pid_t waitpid(pid_t pid, int *status, int options);
参数 :
pid:
pid > 0:等待进程ID为pid的子进程。
pid = -1:等待任意子进程,与wait函数相同。
pid = 0:等待与当前进程的进程组ID相同的任意子进程。
status:
输入输出型参数,一个指向整型的指针,用于获取子进程的终止状态。
options:
WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。
若正常结束,则返回该子进程的ID。
返回值:
如果成功等待到子进程的终止,返回子进程的进程ID;
如果指定的子进程尚未终止,并且使用了WNOHANG选项,则返回0;
如果调用被信号中断,返回-1,并设置errno为EINTR;
如果指定的子进程不存在或不属于当前进程的子进程组,返回-1,并设置errno为ECHILD
status参数
status不能简单的当作整形来看待,可以当作位图来看待,具体细节如下图(只研究status低16比特
位),可以看到只有先判断进程是正常退出后,退出状态码才是有效的。

WIFEXITED 是一个宏(macro),用于检查 wait 或 waitpid 函数返回的子进程状态(status)是否是正常退出。WIFEXITED(status) 接受一个 status 参数,该参数是 wait 或 waitpid 函数返回的子进程状态信息。WIFEXITED 宏会对 status 进行解析,并返回一个非零值(true)表示子进程是正常退出的,返回零值(false)表示子进程不是正常退出的。
如果 WIFEXITED(status) 返回为真,可以使用 WEXITSTATUS(status) 宏来获取子进程的退出状态码。WEXITSTATUS(status) 会返回子进程的退出状态码,该状态码通常是在子进程调用 exit 或返回 main 函数时传递的值。
如果 WIFEXITED(status) 返回为假,可使用WTERMSIG(status),同样是通过wait或waitpid函数获取的子进程的终止状态。如果进程是由于收到信号而异常终止,则WTERMSIG宏返回信号的编号;否则,返回0。
具体使用:
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>int main()
{pid_t pid = fork();if (pid == 0) {// 子进程printf("This is child process\n");// 子进程正常退出,退出状态码为 42exit(42);} else if (pid > 0) {// 父进程int status;wait(&status);if (WIFEXITED(status)) {// 子进程正常退出int exit_status = WEXITSTATUS(status);printf("Child process exited with status: %d\n", exit_status);}else {// 子进程非正常退出WTERMSIG(int status); // WTERMSIG获取异常退出时信号的编号printf("Child process did not exit normally\n");}}else {// fork 出错perror("fork");return 1;}return 0;
}
进程替换
进程替换原理
当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动
例程开始执行,调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。结合下图,进程替换的本质是替换虚拟内存和物理内存/外存的映射关系,故这个过程保留了原进程的task_struct, 和原进程存储堆和栈区中的数据。
需要注意:
- 进程替换后,task_struct 结构体中执行流相关字段会被重置,新的程序加载进来的代码从main函数重新开始执行
- 环境变量存储在环境变量表中,环境变量表也是task_struct的一个字段,所以进行进程切换的用户可以通过调用不同类型的进程替换函数来决定是否保留环境变量
- 进程替换本质没有创建新的task_struct, 也就是说没有创建新的进程,故进程ID不变。
- 堆、栈区数据被保留
- 文件描述符存储在文件描述表中,文件描述符表存储在task_struct中,所以如果在进程替换前如果对文件描述符进行了重定向,重定向的效果会保留到进程替换过后的进程里 。

进程替换函数
#include <unistd.h>`int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
返回值::
成功无返回值
失败返回 -1
参数:
path :可执行文件绝对路径
file :可执行文件名
arg : 可变参数列表
envp : 环境变量数组
argv : 参数数组

记忆方法:
l(list) : 表示参数采用列表
v(vector) : 参数用数组
p(path) : 有p自动搜索环境变量PATH
e(env) : 表示自己维护环境变量
补充/拓展
- 终止信号: 下图前31种信号为进程异常退出时可能接收的信号,信号的具体含义可通过man手册查明。
man 7 signal

- 核心转储 :
有时在本地运行程序时会报错:Segmentation fault (core dumped) ,这表明发生了核心转储。
Linux核心转储(coredump)是指在程序发生崩溃或异常终止时,将程序在崩溃时的内存状态保存到磁盘上的一个文件中。这个文件可以用于调试程序,找出导致程序崩溃的原因。
在Linux系统中,当一个程序崩溃时,默认情况下会生成一个核心转储文件。这个文件包含了程序崩溃时的内存映像、寄存器状态、堆栈信息等。通过分析这个文件,开发人员可以确定程序崩溃的原因,并进行调试。
要启用核心转储功能,可以通过设置ulimit命令来控制。ulimit命令用于设置shell进程的资源限制,其中包括核心转储文件的大小限制。可以使用ulimit -c命令来查看当前的核心转储文件大小限制,使用ulimit -c unlimited命令来设置核心转储文件的大小为无限制。
当程序崩溃时,核心转储文件会被保存在当前工作目录下。可以使用gdb调试器来分析核心转储文件。例如,可以使用gdb程序名核心转储文件来加载核心转储文件并进行调试。
需要注意的是,核心转储文件可能会非常大,因此在生产环境中可能需要限制核心转储文件的大小,以避免磁盘空间被耗尽。另外,核心转储文件可能包含敏感信息,因此在共享或提交给第三方时需要谨慎处理。
- 进程替换的实际使用(位于代码调用cgi模式的部分)
个人代码练习
相关文章:
Linux 进程控制
文章目录 进程创建进程终止进程结果wait函数waitpid函数status参数 进程替换进程替换原理进程替换函数 补充/拓展 进程创建 fork函数 #include <unistd.h>pid_t fork(void);函数返回值: 在父进程中,fork函数返回子进程的进程ID(PID&…...
[ Linux Audio 篇 ] 音频开发入门基础知识
在短视频兴起的背景下,音视频开发越来越受到重视。接下来将为大家介绍音频开发者入门知识,帮助读者快速了解这个领域。 轻柔的音乐、程序员有节奏感的键盘声、嗡嗡的发动机、刺耳的手提钻……这些声音是如何产生的呢?又是如何传到我们耳中的…...
关于高校电子邮件系统开通双因素认证的经验分享-以清华大学为例
清华大学信息化技术中心 马云龙 作者简介: 马云龙,男,清华大学信息化技术中心高级工程师;Coremail管理员社区大咖嘉宾 深耕高校计算机网络/信息化/网络安全岗位20年,对大规模计算机网络及信息系统规划,开发/建设,运维有深刻体会。 目前,越来越多的高校/企业/政府机关…...
「Swift」类淘宝商品瀑布流展示
前言:需要做一个类似于淘宝商品页面的瀑布流展示 结构分析: ps:图片来源 思路分析: 该瀑布流主要还是基于UICollectionView进行展示,只是在cell展示的UICollectionViewFlowLayout需要进行相应调整和自定义ÿ…...
道可云会展元宇宙平台全新升级,打造3D沉浸式展会新模式
随着VR虚拟现实、人工智能、虚拟数字人等元宇宙技术的快速发展,各个行业正试图通过元宇宙技术寻求新的发展突破口,会展行业也不例外。会展作为经贸领域的重要产业形态,越来越多的企业和组织开始寻求通过元宇宙技术为展会赋能,以满…...
Ant Design Pro初始化报错
今天按照官网步骤初始化项目,第一次报错 fatal: unable to access https://github.com/ant-design/ant-design-pro/: SSL certificate problem: unable to get local issuer certificate 致命:无法访问https://github.com/ant-design/ant-design-pro/&…...
第16届中国R会议暨2023X-AGI大会开幕,和鲸科技分享ModelOps在数据科学平台中的实践与应用
11月25日,第 16 届中国 R 会议暨 2023 X-AGI 大会在在中国人民大学逸夫会堂拉开帷幕,本次会议由中国人民大学统计学院、中国人民大学应用统计科学研究中心、统计之都、原灵科技和中国商业统计学会人工智能分会(筹)主办,…...
❀My学习Linux命令小记录(12)❀
目录 ❀My学习Linux命令小记录(12)❀ 46.arp指令 47.tcpdump指令 48.chmod指令 49.chown指令 50.bash调用脚本指令 shell介绍 shell脚本的组成部分 脚本执行方式 检查脚本语法 bash之变量 变量的种类:根据生效的范围不同来区分 …...
MySQL学习day05
DCL(Data Control Language)数据控制语言学习 作用:用来创建数据库用户、控制数据库的访问权限 1)查询用户: use mysql; select * from user; 2)创建用户: create user 用户名主机名 identifi…...
JAVA面试题7
1.Java中的ClassLoader是什么? 它有什么作用? 答案:ClassLoader是一种加载Java类文件的机制,可以从不同的来源加载类文件,如本地文件系统、网络等。ClassLoader可以帮助实现模块化开发和动态加载类等功能。 2.什么是J…...
好用免费的AI换脸5个工具
在当今社会的发展中,人工智能(Artificial Intelligence, AI)扮演着关键的角色,其应用领域不断扩展。作为AI的一个分支,换脸技术近年来备受欢迎。这项技术使得将一个人的面部特征迁移到另一个人的照片或视频成为可能。除…...
【Linux】公网远程访问AMH服务器管理面板
目录 1. Linux 安装AMH 面板2. 本地访问AMH 面板3. Linux安装Cpolar4. 配置AMH面板公网地址5. 远程访问AMH面板6. 固定AMH面板公网地址 AMH 是一款基于 Linux 系统的服务器管理面板,它提供了一系列的功能,包括网站管理、FTP 管理、数据库管理、DNS 管理、…...
随笔-这都是命吗
我与鹏哥、小付有个小群,前几天,鹏哥在群里发了一个图,是他那个城市准备扶持的高新产业,有元宇宙、量子信息、生物制药、人工智能什么的。 先前的时候鹏哥给我说过,当地准备了六百多亩地,准备发展高新产业…...
优化网站性能,从容谈CDN加速的部署与运维
随着互联网的迅猛发展,网站的性能优化成为网站运维工作中不可或缺的一环。其中,CDN(Content Delivery Network)加速技术因其在全球范围内提供快速、可靠的内容分发而备受关注。本文将从一个网站运维的角度出发,深入探讨…...
JavaScript-事件
事件 事件流 指的是事件完整执行过程中的流动路径 两个阶段: 捕获阶段:从大到小冒泡阶段:从小到大 实际开发中都是使用事件冒泡为主 事件捕获 从DOM的根元素开始取执行对应的事件(从外到里) document.addEventLis…...
linux的磁盘管理
Linux 提供了多种工具和技术来进行磁盘管理。下面是对 Linux 磁盘管理的详细解释: 磁盘和分区: 磁盘(硬盘):Linux 系统中的磁盘通常是通过 SATA、SCSI、NVMe 等接口连接的物理硬盘。可以使用工具如 lsblk、fdisk、pa…...
qt-C++笔记之主线程中使用异步逻辑来处理ROS事件循环和Qt事件循环解决相互阻塞的问题
qt-C笔记之主线程中使用异步逻辑来处理ROS事件循环和Qt事件循环解决相互阻塞的问题 code review! 文章目录 qt-C笔记之主线程中使用异步逻辑来处理ROS事件循环和Qt事件循环解决相互阻塞的问题1.Qt的app.exec()详解2.ros::spin()详解3.ros::AsyncSpinner详解4.主线程中结合使用…...
【Docker】从零开始:18.使用Dockerfile构造自己的KingbaseES数据库镜像
【Docker】从零开始:17.使用Dockerfile构造自己的数据库镜像 新建一个自定义目录并创建Dockerfile文件上传需要的文件到自定义目录下注意docker-circle-init.sh文件内容password 内容 开始打包注意打包完成后执行 尝试用工具连接数据库 kingbase.tar.gz 包过大我就上…...
YOLOv8独家改进《全网无重复 YOLOv8专属打造》感知聚合SERDet检测头:简单高效涨点,即插即用|检测头新颖改进
💡本篇内容:YOLOv8独家改进《全网无重复,YOLOv8专属》感知聚合SERDet检测头:高效涨点,即插即用|检测头新颖改进 💡🚀🚀🚀本博客 YOLO系列 + 全新原创感知聚合SERDet检测头 改进创新点改进源代码改进 适用于 YOLOv8 按步骤操作运行改进后的代码即可,附改进源代…...
Android Studio中Flutter项目找不到Android真机设备解决方法
起因:创建正常Android项目可以运行在真机设备上,创建flutter项目就找寻不到Android真机设备。 1:在flutter sdk安装目录按下Shift和鼠标右键,打开Powershell窗口 2:输入以下,然后回车 flutter config --…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
