第 6 天:两个进程怎么传话?又为什么会一起卡住
前两天的生产者和消费者是同一个进程里的两条线程。它们能访问同一块内存所以我们用锁保护共享数据。如果生产者和消费者变成两个进程情况就不同了。两个进程通常各有自己的地址空间在父进程里修改一个普通变量子进程不会因此看到修改。它们需要一条专门的通信通道。今天先用最容易看清的管道传一次话然后追一个很常见的故障数据明明已经传完程序却一直不退出。管道是一条字节通道在终端输入printfhello\n|wc-cprintf产生文字wc -c统计收到的字节数。中间的|让 Shell 建立管道把前一个程序的输出接到后一个程序的输入。管道可以理解成由内核管理的一条字节通道。一端写入另一端读取写入进程 ──写端 [ 内核中的管道 ] 读端──→ 读取进程读端暂时没有数据、但仍有写端开着时读取会等待。所有写端都关闭而且剩余数据已读完后读取才会得到“结束了”的结果。在 C 里这表现为read返回0。**管道传的是字节流没有替你划分“第一条消息”“第二条消息”。**写入方一次写了多少字节读取方不一定恰好用一次read收到同样多的字节。自己用pipe和fork传一次把下面代码保存为pipe_demo.c。父进程写入Hi!子进程一直读到管道结束#includestdio.h#includesys/types.h#includesys/wait.h#includeunistd.hintmain(void){intfd[2];if(pipe(fd)-1){perror(pipe);return1;}pid_tpidfork();if(pid-1){perror(fork);close(fd[0]);close(fd[1]);return1;}if(pid0){close(fd[1]);/* 子进程只读关掉自己的写端 */charch;ssize_tn;while((nread(fd[0],ch,1))1){putchar(ch);}close(fd[0]);if(n-1){perror(read);return1;}return0;}close(fd[0]);/* 父进程只写关掉自己的读端 */constchar*messageHi!\n;for(constchar*pmessage;*p!\0;p){if(write(fd[1],p,1)!1){perror(write);close(fd[1]);waitpid(pid,NULL,0);return1;}}close(fd[1]);/* 告诉读端不会再有数据了 */if(waitpid(pid,NULL,0)-1){perror(waitpid);return1;}return0;}编译运行gcc-Wall-Wextra-opipe_demo pipe_demo.c ./pipe_demo输出是Hi!这里一次只写、读一个字节是为了让例子集中在管道和关闭操作上。实际程序通常按缓冲区读写还要处理一次调用只传输部分数据的情况。最关键的是那几个closepipe(fd)给出两个文件描述符fd[0]是读端。fd[1]是写端。随后调用fork。第二天讲过子进程会继承父进程已打开的文件描述符。所以fork之后父子进程各自都持有读端和写端。它们必须关掉自己不用的那一端。试着把子进程里的这一行注释掉close(fd[1]);再运行程序很可能一直不退出。原因值得沿着代码走一遍父进程写完Hi!关闭自己的写端。子进程读完这些字节再次调用read等着管道结束。可子进程自己还开着一个写端。内核看到仍有写端就不能告诉读端“以后再也没有数据”。父进程正在waitpid中等子进程退出子进程正在等一个不会到来的结束信号。这类故障不靠多分 CPU 时间解决。两个进程都在等待真正需要查的是各自等什么让它继续的条件还能发生吗实验卡住时可以按CtrlC结束再恢复那行close。管道代码里关闭不用的端口不是收尾细节它会直接影响读端能否判断结束。进程通信不止管道管道适合传递连续的字节Shell 里把几个程序接起来尤其方便。它也有边界普通管道是单向的要双向通信需要两条管道或使用其他机制。如果两个进程需要访问同一大块数据可以使用共享内存。它减少来回复制数据的需要但共享之后也会遇到前两天的问题谁先写、谁能读、怎样避免同时修改。管道把传输过程交给内核管理共享内存则把协调访问的责任更多地留给程序。还有消息队列、套接字等方式。今天先抓住共同点进程默认没有“直接读取对方普通变量”的能力通信必须通过明确建立的机制。两把锁也能让线程永久等待管道里的等待提醒了我们再回头看锁。如果两条线程需要两把锁却按相反顺序获取线程 A先拿 X再等 Y 线程 B先拿 Y再等 X假设 A 已拿到 XB 已拿到 Y。接下来 A 等 B 放开 YB 等 A 放开 X谁都无法继续。这就是典型的死锁。它成立时几件事同时发生锁一次只能归一方持有线程拿着已有的锁还要等另一把别人不能强行夺走它手里的锁等待关系最后绕成了一个圈。只说“程序在等锁”还不足以判定死锁——如果持锁线程还能继续工作并最终释放锁等待就会结束。对上面的例子一个直接的修法是规定顺序**所有线程都先拿 X再拿 Y释放时反过来。**这样不会出现 A 拿 X 等 Y、B 拿 Y 等 X 的等待圈。实际项目中一旦某段代码要持有多把锁统一加锁顺序比事后排查死锁省心得多。今天两个例子表面不同排查方法却相通。看到程序“卡住”别急着猜它是不是运行太慢。先画出等待关系**谁在等谁谁手里还握着让对方继续所需的资源**管道的写端、互斥锁都可能是那张图上的关键一环。到这里我们从进程、线程一路讲到了它们怎样协作。下一天换一个方向程序使用的内存地址真的是内存条上的位置吗

相关新闻

Mac mini 部署 GUI Agent 实战:Mano-P 安装配置与自动化任务指南

Mac mini 部署 GUI Agent 实战:Mano-P 安装配置与自动化任务指南

1. 为什么要在 Mac mini 上折腾 GUI Agent先说结论:Mac mini 是目前性价比最高的 GUI Agent 常驻设备之一。我前后用过 N100 小主机、老款笔记本、云服务器来跑自动化任务,最后稳定留在桌角的是一台 M 系列芯片的 Mac mini。原因很直接——功耗低到可以 …

2026/10/4 4:08:06 阅读更多 →
N32G45x从Keil到ARM GCC完整迁移指南(含CMake与烧录调试)

N32G45x从Keil到ARM GCC完整迁移指南(含CMake与烧录调试)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 4:08:06 阅读更多 →
这份工作我该不该投?ResumeSkills职位匹配度分析与红牌预警实战指南

这份工作我该不该投?ResumeSkills职位匹配度分析与红牌预警实战指南

这份工作我该不该投?ResumeSkills职位匹配度分析与红牌预警实战指南 【免费下载链接】ResumeSkills A collection of AI agent skills focused on resume optimization, job applications, and career development. Built for job seekers, career changers, and pr…

2026/10/4 4:08:06 阅读更多 →

最新新闻

单片机AT指令非阻塞配置模块模板:状态机与超时重试机制

单片机AT指令非阻塞配置模块模板:状态机与超时重试机制

搞单片机开发的朋友,十有八九都跟AT指令打过交道。WiFi模块要配ESP8266,蓝牙模块要配HC-05,4G模块要配EC200,GPS模块要配ATGM336H,甚至不少传感器模块都爱用AT指令来设置参数。AT指令本身逻辑很简单,就是“…

2026/10/4 4:41:25 阅读更多 →
Xilinx FPGA上MIPI DPHY接口实战:从CSI-2采集到DSI显示的全流程解析

Xilinx FPGA上MIPI DPHY接口实战:从CSI-2采集到DSI显示的全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 4:41:25 阅读更多 →
复合光源仿真实用指南:VirtualLab Fusion建模全流程解析

复合光源仿真实用指南:VirtualLab Fusion建模全流程解析

做光学系统仿真的人,早晚都会卡在光源这一步。单色平面波确实能解决很多衍射、干涉问题,可一旦你开始处理真实光源——白光LED、多模激光二极管、宽谱超连续谱——就会发现结果怎么都对不上实验,干涉条纹宽度不对、对比度偏大、色散效应完全看…

2026/10/4 4:41:25 阅读更多 →
STM32电梯面板开发实战:从硬件选型到RS485通讯与状态机设计

STM32电梯面板开发实战:从硬件选型到RS485通讯与状态机设计

前阵子帮朋友处理一栋老写字楼的电梯召唤盒问题时,我蹲在门口拆开那台用了十几年的设备,里面是一排继电器和一堆已经发黑的触点。电梯每停一层,盒子里的继电器就噼里啪啦响一阵,楼层指示灯用的小灯泡也黑了两只。我当时就跟朋友说…

2026/10/4 4:41:25 阅读更多 →
分支功能:实现脚本多场景覆盖

分支功能:实现脚本多场景覆盖

分支功能:实现多场景覆盖主线描述脚本要做的功能,分支描述该功能在各条路径上的执行情况。 一份代码,配上 N 个分支场景,得到 N 份测试结论。 项目地址:https://qingxun.online一、问题:脚本在正常情况下通…

2026/10/4 4:41:25 阅读更多 →
Oil Motion三大交付路线全解析:烘焙视频、绿幕视频与透明雪碧图如何自动选型

Oil Motion三大交付路线全解析:烘焙视频、绿幕视频与透明雪碧图如何自动选型

Oil Motion三大交付路线全解析:烘焙视频、绿幕视频与透明雪碧图如何自动选型 【免费下载链接】oil-motion 设计并实现随滚动、拖动、指针或状态变化响应的网页动画,覆盖素材、时间轴和运行时。 项目地址: https://gitcode.com/gh_mirrors/oi/oil-motio…

2026/10/4 4:40:24 阅读更多 →

日新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:35 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:36 阅读更多 →