当前位置: 首页 > article >正文

(Linux)进程控制

进程创建在代码中进程创建用的是fork函数调用fork函数后操作系统会为子进程分配内存块和进程控制块PCB并将父进程PCB的部分内容拷贝至子进程。接着将子进程添加到系统进程列表中也就是系统管理进程的链表中最后fork函数返回调度器调度子进程。我们知道为了提高内存空间的利用率减少创建子进程的时间在父进程刚创建子进程时数据和代码是二者共用的其中一方需要修改某一部分数据时才会触发写时拷贝。而触发写时拷贝的关键就是页表中的权限。在创建子进程前父进程的数据段是可以修改的也就是页表中标记了该部分有写的权限但当子进程创建后就会被改为只读的。若父子进程中有一方尝试通过虚拟地址修改数据段的内容由于内存管理单元MMU通过页表发现这个地址是只读的经过一系列的信息传递最终操作系统会收到这个修改只读区域的错误但操作系统经过检测发现这个虚拟地址属于该进程的数据段而数据段是可以修改的于是触发写实拷贝。如下进程退出进程会在两种情况下退出一是代码运行完毕二是异常终止。对于前者main函数的返回值就是进程退出时的退出码通常表明了程序的运行情况返回0表示运行结果正确返回非0则表示结果错误。返回值会写到进程的task_struct内部。使用命令 echo $ 即可查看上一个结束的进程的退出码也就是main函数的返回值。如果是异常终止的情况进程的退出码就没有意义了。使用函数strerror即可查看退出码对应的含义。如下#includestdio.h #includestring.h int main(){ for(int i0;i200;i){ printf(error[%d] : %s\n,i,strerror(i)); } return 0; }也可以调用exit函数让进程主动退出在代码的任何地方调用exit函数都会让进程退出。此时的退出码是传入exit的参数。如exit(3)就返回3。还有另一个类似的函数是_exit函数二者的区别是 _exit 属于系统调用函数exit则属于C语言的库函数exit内部就是通过调用_exit终止进程的进程使用exit退出时会对各个缓冲区进行刷新如果是用_exit退出则会直接终止进程。进程等待子进程退出后其父进程需要接收子进程的退出信息并回收资源否则子进程就会进入僵尸状态用命令都杀不掉毕竟已经死了。那么具体如何操作呢答案是调用函数wait或waitpid进行等待当然不只是等子进程退出子进程退出后这两个函数会接收子进程的退出信息并回收资源彻底终结子进程。下面是进程等待的两个函数wait和waitpid的定义其中_Nullabel是一个类型修饰符type qualifier用于表示指针可以为空。这两个函数都会将子进程的退出信息传到参数wstatus指向的空间这种用于输出的参数被称为输出型参数这些子进程的退出信息就是操作系统从子进程的task_struct中拷贝过来的。我们先看比较简单的wait函数。wait的原理就是让父进程阻塞在wait调用处一直等待直到子进程退出。等待成功会返回回收的子进程的pid否则一般返回-1wait函数不会返回0。等待结束后从参数wstatus传出的并不是退出码而是类似位图的信息模式。我们知道int类型有32位的空间在wait传出的这32位的信息中左边16位无意义不用管右边的16位如下如果该进程是正常退出的左起8位就是退出码右边8位无意义。如果是异常退出的左起8位无意义右边8位中最左边的一位是core dump标志暂时不用管剩下的7位是终止信号。如果不想通过位运算提取退出码可以使用库中定义的宏如下WIFEXITED(status)用于查看进程是否是正常退出。若为正常终止子进程返回的状态则为真反之则为假。WEXITSTATUS(status)用于查看进程的退出码。若WIFEXITED非零也就是正常退出则提取子进程退出码。终止信号以及其它信号相关内容会在之后讲解信号相关内容时一起讲解。接着我们来看waitpid函数它的功能更全面返回值和参数wstatus的用法和wait函数一样。比较特殊的是waitpid可以返回0这个后面讲解。waitpid函数可以指定等待哪个或哪些子进程参数pid为-1时waitpid会和wait一样等待所有子进程大于0时则是等待对应pid的进程等于0的情况可以先不管它的功能是等待同一个进程组的所有子进程。参数options是用来选择等待方式的。前面提到调用wait时如果子进程未运行完毕父进程会阻塞在wait调用处这种等待方式叫做阻塞式等待waitpid函数如果选项参数options为0也是采用这种等待方式。如果要采用非阻塞等待的方式则可以使用选项WNOHANG它是宏定义的 1。具体来说传入该选项后waitpid函数只会检查一次子进程是否结束如果结束了就正常接收退出信息回收资源如果没结束也不会一直等待子进程结束而是直接返回0这就是非阻塞等待。waitpid返回值中的0就是这个用法。不过为了确保能够回收子进程一般是把传入WNOHANG选项的waitpid函数写进循环中不断检查子进程是否运行结束的同时还可以执行其它代码这时可以使用函数指针数组每次循环调用不同的函数如下。这种父进程没有被阻塞但是不停地检查的等待方式叫做非阻塞轮询。要注意虽然WNOHANG的值是1但不要直接用1代替一是这样降低代码可读性二是在某些系统下有出错的风险。#includestdio.h #includeunistd.h #includesys/wait.h void Download(){ printf(下载已开始\n); sleep(1); printf(下载已结束\n); } void function1(){ printf(功能一已启用\n); sleep(1); printf(功能一已结束\n); } void function2(){ printf(功能二已启用\n); sleep(1); printf(功能二已结束\n); } void function3(){ printf(功能三已启用\n); sleep(1); printf(功能三已结束\n); } void(*func[5])(void); int main(){ func[0]Download; func[1]function1; func[2]function2; func[3]function3; int pidfork(); if(pid0){//子进程 sleep(10); } else{//父进程 int wstatus,i0; while(!waitpid(pid,wstatus,WNOHANG)){ if(i5 func[i]){ func[i](); } else{ printf(准备就绪正在等待子进程结束...\n); sleep(2); } i; } if(WIFEXITED(wstatus)) printf(子进程运行完成返回值为%d\n,WEXITSTATUS(wstatus)); else printf(子进程运行失败\n); } return 0; }如果忘记函数指针数组的相关知识可以看我之前写的文章C语言指针的初步了解与深入解析-CSDN博客进程程序替换使用execl函数可以实现让代码使用命令。path是指令对应文件的路径剩下的就是命令的内容命令怎么写我们就怎么传按空格划分命令再传入然后以NULL结尾即可。int execl(const char *path, const char *arg, ...);比如我们要使用命令 ls -a -l 就用下面的方式传入execl(usr/bin/ls,ls,-l,-a,NULL);多个选项组合在一起的形式不用另外拆分比如 ls -al 就分成 ls 和 -al 传入即可。调用execl函数后该进程剩下的代码不再被执行而是被替换为命令ls这就是程序替换。在程序替换的过程中没有创建新的进程只是用新的进程的代码和数据覆盖式地替换当前进程的代码和数据。程序替换成功后原始代码中处于execl函数后面的部分就不存在了。所以替换成功时execl函数不会返回任何值只有替换失败才会返回-1。 如果既想要执行命令又想保留程序剩下的部分可以用fork创建子进程让子进程去调用execl函数。子进程的代码段原本是和父进程共用的当进行程序替换时代码段也会触发写时拷贝。像这样以exec开头的可以使用命令的函数一共有7个#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[]); int execvpe(const char *file, char *const argv[], char *const envp[]);事实上,只有execve是真正的系统调用,其它六个个函数最终都调用execve。这些函数看起来很容易记混但其实是有命名规则在的​l (list)​: 参数以列表​的形式传递就是像上面那样逐个直接写入函数参数中。​v (vector)​: 参数以数组​的形式传递即传入一个以NULL结尾的字符串指针数组。​p (path)​: 带有该后缀的函数会通过环境变量 PATH​ 来查找可执行文件。不需要完整路径提供文件名即可。​e (env)​: 带有该后缀的函数可以传入环境变量​数组并用传入的环境变量数组覆盖原有的环境变量数组。如果想传入现有的环境变量可以将头文件unistd.h里面的字符二级指针char** environ传入。exec函数的本质其实就是找到可执行文件然后用传入的命令调用。因此除了使用指令外exec函数还可以调用各种程序。方法是一样的命令怎么写参数就怎么传。这样就可以实现在C语言代码中调用Java程序、C程序甚至是脚本。这些exec函数其实就是加载器底层调用的接口。加载器也是操作系统的一部分主要功能是将程序从硬盘或其他存储设备加载到内存中并为其运行做好一切准备。关于加载器感兴趣的可以自行了解。本文到此结束感谢观看

相关文章:

(Linux)进程控制

进程创建 在代码中,进程创建用的是fork函数,调用fork函数后,操作系统会为子进程分配内存块和进程控制块(PCB),并将父进程PCB的部分内容拷贝至子进程。接着,将子进程添加到系统进程列表中&#x…...

ARM架构CNTP_CTL_EL0定时器寄存器详解与应用

1. ARM架构定时器控制寄存器概述在ARMv8/v9架构中,定时器系统是处理器时间管理的关键组件。CNTP_CTL_EL0作为物理定时器的控制寄存器,主要负责EL1(操作系统内核级)的物理定时器控制。这个64位寄存器虽然只使用了最低3位,却承载着定时器状态监…...

用Matlab给信号“搬家”:手把手教你将中频采样数据转为IQ格式(附完整代码)

用Matlab给信号“搬家”:手把手教你将中频采样数据转为IQ格式(附完整代码) 在无线通信系统测试和算法验证中,我们常常会遇到这样的场景:从频谱仪或采集卡获取的中频信号数据(如.mat文件)&#x…...

Material Design Lite图片优化:提升网页性能的终极指南

Material Design Lite图片优化:提升网页性能的终极指南 【免费下载链接】material-design-lite Material Design Components in HTML/CSS/JS 项目地址: https://gitcode.com/gh_mirrors/ma/material-design-lite Material Design Lite是一个轻量级的前端框架…...

软件忘了“擦黑板”:一次内核信息泄露事件(CVE-2024-49997)的深度剖析

想象一下,老师在用过的黑板上写字,没擦干净就直接开讲——网络世界里,这个“忘记擦黑板”的疏忽,可能导致整个系统的安全基石被悄然洞穿。 引言:一个不寻常的“内存泄露” 在程序员的世界里,提到“内存泄露…...

无射频芯片实现LoRa通信:LoLRa项目技术解析

1. LoLRa项目概述:无射频芯片的LoRa通信方案在物联网设备开发中,Semtech的LoRa射频芯片一直是实现远距离通信的主流选择。但最近开源的LoLRa项目展示了一种颠覆性思路——仅通过普通MCU的I2S或SPI接口就能生成可被商用LoRa网关识别的信号。这个由CNLohr开…...

3大核心优势解锁纯净音乐体验:MoeKoeMusic开源播放器深度解析

3大核心优势解锁纯净音乐体验:MoeKoeMusic开源播放器深度解析 【免费下载链接】MoeKoeMusic 一款开源简洁高颜值的酷狗第三方客户端 An open-source, concise, and aesthetically pleasing third-party client for KuGou that supports Windows / macOS / Linux / W…...

告别色彩失真:flv.js如何让YUV视频在浏览器绚丽绽放

告别色彩失真:flv.js如何让YUV视频在浏览器绚丽绽放 【免费下载链接】flv.js HTML5 FLV Player 项目地址: https://gitcode.com/gh_mirrors/fl/flv.js 在数字视频播放的世界里,色彩还原度直接影响着观看体验。HTML5 FLV Player(flv.js…...

从零开始打造OS性能监控:基于os-tutorial的计时器与中断完全指南

从零开始打造OS性能监控:基于os-tutorial的计时器与中断完全指南 【免费下载链接】os-tutorial How to create an OS from scratch 项目地址: https://gitcode.com/gh_mirrors/os/os-tutorial os-tutorial是一个从零开始构建操作系统的开源项目,它…...

京东工业与中交二航巴西公司战略合作,推动巴西属地化供应链能力升级

京东工业与中交二航巴西签署超深度合作协议4月21日,京东工业巴西有限公司和中交二航巴西工程有限公司(CHEC - BR)在巴西签署战略合作协议。双方将在渠道、供应链和MRO(维护、维修和运营物资)采购方面开展深度合作&…...

JCSprout事务管理终极指南:声明式与编程式事务对比分析

JCSprout事务管理终极指南:声明式与编程式事务对比分析 【免费下载链接】JCSprout 👨‍🎓 Java Core Sprout : basic, concurrent, algorithm 项目地址: https://gitcode.com/gh_mirrors/jc/JCSprout JCSprout作为Java核心知识的学习…...

如何实现XState状态机日志记录:完整的变更追踪与审计指南

如何实现XState状态机日志记录:完整的变更追踪与审计指南 【免费下载链接】xstate State machines, statecharts, and actors for complex logic 项目地址: https://gitcode.com/gh_mirrors/xs/xstate XState是一个强大的状态管理库,用于构建复杂…...

3步永久保存微信聊天记录的终极解决方案:WeChatMsg完全指南

3步永久保存微信聊天记录的终极解决方案:WeChatMsg完全指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/…...

终极指南:使用XState实现灵活高效的权限管理系统

终极指南:使用XState实现灵活高效的权限管理系统 【免费下载链接】xstate State machines, statecharts, and actors for complex logic 项目地址: https://gitcode.com/gh_mirrors/xs/xstate 在现代应用开发中,权限管理是确保系统安全和用户体验…...

别再让AI生成视频糊成马赛克了!手把手教你用Topaz Video AI 4.0无损放大(附Win/Mac预设参数)

从马赛克到4K:用Topaz Video AI拯救AI生成视频的终极指南 当你在Pika或Runway上兴奋地生成了一段创意视频,却发现画面糊得像隔了层毛玻璃——这种失望感我太熟悉了。AI视频生成工具虽然打开了创意新世界,但分辨率问题始终是硬伤。别急着放弃你…...

ViGEmBus终极指南:5分钟搞定Windows游戏手柄模拟难题

ViGEmBus终极指南:5分钟搞定Windows游戏手柄模拟难题 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 你是否遇到过这样的困扰?手头有…...

如何用AiZynthFinder在3分钟内完成复杂分子的AI逆合成路线设计?

如何用AiZynthFinder在3分钟内完成复杂分子的AI逆合成路线设计? 【免费下载链接】aizynthfinder A tool for retrosynthetic planning 项目地址: https://gitcode.com/gh_mirrors/ai/aizynthfinder 想象一下,你是一位药物研发化学家,面…...

SAP FI实操笔记:中日会计科目对照表,手把手教你配置GL主数据

SAP FI中日会计科目智能配置实战:从对照表到系统落地的全流程解析 当东京证券交易所的上市公司需要合并其在华子公司报表时,财务团队总会在会计科目转换环节遭遇"术语迷阵"。某日企财务总监曾向我展示过他们手工维护的Excel对照表——超过2000…...

Viper配置加密方案:安全存储敏感配置信息的终极指南

Viper配置加密方案:安全存储敏感配置信息的终极指南 【免费下载链接】viper Go configuration with fangs 项目地址: https://gitcode.com/gh_mirrors/vi/viper Viper作为Go语言生态中强大的配置管理工具,不仅提供了灵活的配置读取能力&#xff0…...

从区间锁到行锁:一次高并发写入死锁治理实战

资源账户写入链路长期存在 MySQL 死锁报警,日常量级达到 99。虽然业务层依赖消息总线重试后多数请求可以成功,但从数据库和链路治理角度看,这类问题已经属于稳定存在的并发设计缺陷。 本次治理聚焦一个典型场景:同一 uid 并发发放…...

3步掌握Textractor:游戏文本提取神器,让外语游戏无障碍畅玩

3步掌握Textractor:游戏文本提取神器,让外语游戏无障碍畅玩 【免费下载链接】Textractor Extracts text from video games and visual novels. Highly extensible. 项目地址: https://gitcode.com/gh_mirrors/te/Textractor 还在为看不懂日语RPG的…...

Gramps家谱软件完整指南:如何轻松构建您的家族历史数据库

Gramps家谱软件完整指南:如何轻松构建您的家族历史数据库 【免费下载链接】gramps Source code for Gramps Genealogical program 项目地址: https://gitcode.com/gh_mirrors/gr/gramps 您是否曾为家族历史资料零散而烦恼?是否想系统整理祖辈故事…...

React Boilerplate接近检测与交互优化:构建现代化用户体验的终极指南

React Boilerplate接近检测与交互优化:构建现代化用户体验的终极指南 【免费下载链接】react-boilerplate 🔥 A highly scalable, offline-first foundation with the best developer experience and a focus on performance and best practices. 项目…...

如何快速掌握WindowResizer:3分钟学会强制调整任意窗口大小的完整指南

如何快速掌握WindowResizer:3分钟学会强制调整任意窗口大小的完整指南 【免费下载链接】WindowResizer 一个可以强制调整应用程序窗口大小的工具 项目地址: https://gitcode.com/gh_mirrors/wi/WindowResizer 还在为那些顽固不化、无法调整大小的应用程序窗口…...

如何用The Super Tiny Compiler掌握作用域与符号表管理:完整指南

如何用The Super Tiny Compiler掌握作用域与符号表管理:完整指南 【免费下载链接】the-super-tiny-compiler :snowman: Possibly the smallest compiler ever 项目地址: https://gitcode.com/gh_mirrors/th/the-super-tiny-compiler The Super Tiny Compiler…...

如何用NSC_BUILDER轻松管理你的Switch游戏文件:3个实用技巧

如何用NSC_BUILDER轻松管理你的Switch游戏文件:3个实用技巧 【免费下载链接】NSC_BUILDER Nintendo Switch Cleaner and Builder. A batchfile, python and html script based in hacbuild and Nuts python libraries. Designed initially to erase titlerights enc…...

解放双手:MediaFire 批量下载神器,一键获取海量资源

解放双手:MediaFire 批量下载神器,一键获取海量资源 【免费下载链接】mediafire_bulk_downloader Script for bulk downloading entire mediafire folders for free using python. 项目地址: https://gitcode.com/gh_mirrors/me/mediafire_bulk_downlo…...

终极Python指南实战:数据一致性保证的完整解决方案

终极Python指南实战:数据一致性保证的完整解决方案 【免费下载链接】python-guide Python best practices guidebook, written for humans. 项目地址: https://gitcode.com/gh_mirrors/py/python-guide Python指南(python-guide)是一…...

OpCore Simplify:告别黑苹果配置难题,四步构建完美EFI

OpCore Simplify:告别黑苹果配置难题,四步构建完美EFI 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 还在为黑苹果复杂的Open…...

Boomi将在2026年Boomi World大会上发布数据激活和AI驱动创新的未来规划

这场全球顶级盛会将重点展示各类组织如何激活数据,为AI到商业智能的各类应用提供支持 数据激活公司Boomi今日宣布举办2026年Boomi World大会,这是该公司一年一度的顶级用户大会,将于2026年5月11日至14日在伊利诺伊州芝加哥举行。本次大会将汇…...