新闻详情

新闻详情

首页 / 资讯中心 / 详情

第 2 天:Shell 是怎么启动另一个程序的?

发布时间:2026/11/15 1:22:17来源:尧图网络
第 2 天:Shell 是怎么启动另一个程序的?
昨天我们运行了./hello。程序从磁盘上的文件变成了进程但中间留了一个问题正在运行的 Shell怎样让另一个程序跑起来在 Linux 中常见做法可以概括为三个动作fork创建子进程 exec让子进程运行新程序 wait父进程等待并取得结果只记住这三个词还不够。真正容易弄混的是fork之后父子进程各从哪里继续运行exec会不会再创建一个进程子进程结束后又为什么还需要wait我们用两个小程序把它们看清楚。先写一个要被启动的程序把下面的代码保存为worker.c#includestdio.h#includeunistd.hintmain(void){printf(新程序正在运行PID%ld\n,(long)getpid());return7;}它只做两件事打印自己的进程号然后以状态码7退出。接着写启动它的程序保存为launcher.c#includestdio.h#includesys/types.h#includesys/wait.h#includeunistd.hintmain(void){printf(父进程PID%ld\n,(long)getpid());fflush(stdout);pid_tpidfork();if(pid-1){perror(fork);return1;}if(pid0){printf(子进程exec 前 PID%ld\n,(long)getpid());fflush(stdout);execl(./worker,worker,(char*)NULL);perror(execl);_exit(127);}printf(父进程创建了子进程 %ld等待它结束\n,(long)pid);intstatus;if(waitpid(pid,status,0)-1){perror(waitpid);return1;}if(WIFEXITED(status)){printf(父进程子进程的退出码是 %d\n,WEXITSTATUS(status));}return0;}编译并运行gcc-Wall-Wextra-oworker worker.c gcc-Wall-Wextra-olauncher launcher.c ./launcher你会看到类似结果父进程PID3200 父进程创建了子进程 3201等待它结束 子进程exec 前 PID3201 新程序正在运行PID3201 父进程子进程的退出码是 7中间父进程和子进程的打印先后可能变化最后一行一定要等子进程结束后才会出现。更值得留意的是exec前后子进程的 PID 都是 3201。fork之后为什么两边都继续运行程序运行到这一行pid_tpidfork();操作系统创建一个子进程。从这一行返回后父进程和子进程都会继续执行后面的代码只是拿到的返回值不同谁在执行fork()的返回值父进程子进程的 PID是一个正数子进程0创建失败-1不会产生子进程因此同一段代码可以通过if (pid 0)判断“现在运行到这里的是子进程”。子进程也不是从main的第一行重新跑一遍。它从fork返回的位置继续执行。父子进程此后各走各的父进程可以等待子进程可以去运行别的程序。常说fork“复制进程”但别理解为它立刻把所有内存逐字节复制一遍。父子进程起初看到的内存内容相同现代 Linux 通常使用写时复制先共享相关的物理内存页等一方修改时再为它准备独立的页。对程序来说它们仍是两个拥有各自地址空间的进程。fork还会让子进程继承父进程已打开的文件描述符。Shell 正是利用这一点在运行新程序前接好输入、输出或管道。我们讲管道时会用到它。exec做的不是“再生一个进程”子进程接着执行execl(./worker,worker,(char*)NULL);它要求运行./worker。这个函数属于exec函数族最终会使用execve系统调用。**exec把当前进程运行的程序换掉但进程仍然是这个进程。**它的 PID 不变所以例子里worker打印出的 PID与调用execl前子进程打印的 PID 相同。替换之后原来launcher在子进程中的代码、栈等程序内容不再照旧运行新程序从自己的入口开始执行最终进入worker的main。父进程则没有被替换它仍在launcher里等待。这也解释了代码中一个看着有点奇怪的地方execl(./worker,worker,(char*)NULL);perror(execl);_exit(127);如果execl成功它不会返回到下一行。只有找不到文件、没有执行权限等导致它失败时才会执行perror。随后用_exit(127)结束子进程避免它误跑到后面属于父进程的逻辑。这里的127是这个示例为启动失败选用的退出码不是exec规定的统一错误码。父进程等的是什么父进程拿到子进程的 PID 后调用waitpid(pid,status,0);它会等待指定的子进程结束并取得子进程的终止信息。等待期间父进程不需要自己写一个循环反复检查操作系统可以让它暂时休眠把 CPU 用在别的任务上。status不能直接当成退出码使用。我们先用WIFEXITED(status)判断子进程是否正常退出再用WEXITSTATUS(status)取出worker返回的7。如果子进程是被信号终止的就属于另一种情况。那不调用waitpid行不行子进程结束后它占用的大部分资源会被释放但内核还要暂时保留少量记录包括 PID 和退出状态好让父进程来领取结果。在父进程尚未领取的这段时间里它被称为僵尸进程。“僵尸”听起来很吓人实际上它已经不执行代码了问题在于如果父进程长期不回收大量子进程这些记录会持续占用系统资源。wait或waitpid就是父进程领取结果、完成回收的方式。再看一次 Shell 做的事当你在交互式 Shell 中输入./hello通常会发生这样的过程Shell │ ├─ fork创建子进程 │ │ │ └─ exec子进程运行 ./hello │ └─ wait等待子进程结束取得执行结果程序结束后Shell 还在所以你会重新看到命令提示符。如果在命令后加让它在后台运行Shell 对等待的安排就会不同但“创建进程再运行程序”这条主线没有变。今天最该弄清的不是三个函数名而是它们各自解决的问题fork解决“谁来运行”exec解决“运行什么”wait解决“运行完怎样收尾”。明天继续追一个问题Shell、浏览器和音乐播放器都准备好了CPU 究竟先运行谁
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/11/14 3:51:47

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/11/12 23:59:09

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/11/14 10:11:15

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/11/14 17:14:38

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/11/14 16:35:50

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/11/14 3:51:43

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉