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 --…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

Visual Studio Code 扩展
Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后,命令 changeCase.commands 可预览转换效果 EmmyLua…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能
指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...
深入解析 ReentrantLock:原理、公平锁与非公平锁的较量
ReentrantLock 是 Java 中 java.util.concurrent.locks 包下的一个重要类,用于实现线程同步,支持可重入性,并且可以选择公平锁或非公平锁的实现方式。下面将详细介绍 ReentrantLock 的实现原理以及公平锁和非公平锁的区别。 ReentrantLock 实现原理 基本架构 ReentrantLo…...
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.
这个警告表明您在使用Vue的esm-bundler构建版本时,未明确定义编译时特性标志。以下是详细解释和解决方案: 问题原因: 该标志是Vue 3.4引入的编译时特性标志,用于控制生产环境下SSR水合不匹配错误的详细报告1使用esm-bundler…...