【linux】第四天 dup文件描述符复制函数和管道详解

发布时间:2026/9/11 15:15:14

【linux】第四天 dup文件描述符复制函数和管道详解 目录一、文件描述符复制1、dup函数复制文件描述符​编辑 2、dup2函数复制文件描述符​编辑 二、无名管道pipe1、概述2、无名管道的创建3、无名管道读写的特点4、无名管道ps -A | grep bash实现三、有名管道FIFO命名管道1、概述2、创建有名管道 mkfifo3、有名管道读写的特点一、文件描述符复制让新的文件描述符 指向 旧的文件描述符。新旧文件描述符指向同一个文件 使用的函数dup、dup2。1、dup函数复制文件描述符#includeunistd.hint dup(int oldfd);dup函数的功能从系统中寻找最小可用的文件描述符 作为oldfd的副本。 新文件描述符 通过dup的返回值返回。2、dup2函数复制文件描述符#includeunistd.hint dup2(int oldfd, int newfd);dup2的功能将newfd作为oldfd的副本。 如果newfd事先存在 dup2会先close(newfd)然后将newfd作为oldfd的副本。二、无名管道pipe1、概述管道(pipe)又称无名管道。 无名管道是一种特殊类型的文件在应用层体现为两个打开的文件描述符读端和写端。管道的特点半双工数据在同一时刻只能在一个方向上流动。数据只能从管道的一端写入从另一端读出。写入管道中的数据遵循先入先出的规则。管道所传送的数据是无格式的这要求管道的读出方与写入方必须事先约定好数据 的格式 如多少字节算一个消息等。管道不是普通的文件不属于某个文件系统其只存在于内存中。管道在内存中对应一个缓冲区。不同的系统其大小不一定相同。从管道读数据是一次性操作数据一旦被读走它就从管道中被抛弃释放空间以便写更多的数据。管道没有名字只能在具有公共祖先的进程之间使用2、无名管道的创建#includeunistd.hint pipe(int filedes[2]);功能经由参数filedes返回两个文件描述符参数 filedes为int型数组的首地址其存放了管道的文件描述符fd[0]、fd[1]。filedes[0]为读而打开filedes[1]为写而打开管道filedes[0]的输出是filedes[1]的输 入。返回值 成功返回 0 失败返回-1注意在使用无名管道的时候 必须事先确定谁发谁收的问题。一旦确定不可更改。#include stdio.h #include unistd.h #include string.h #include sys/wait.h int main(int argc, char const *argv[]) { //创建一个无名管道 int fd[2]; pipe(fd); //创建一个子进程 //父进程发 子进程收 pid_t pidfork(); if(pid0)//子进程 { //子进程的写端无意义可以事先关闭 close(fd[1]); //子进程接收父进程消息 unsigned char buf[128]; printf(子进程%d正在等待父进程的消息\n, getpid()); read(fd[0],buf,sizeof(buf)); printf(子进程%d读到的消息为:%s\n, getpid(), buf); //子进程读完数据 应该关闭读端 close(fd[0]); //显示退出 _exit(-1); } if(pid0) //父进程 { //父进程的读端无意义可以事先关闭 close(fd[0]); //写端写入数据 printf(3秒后父进程%d写入数据hello pipe\n,getpid()); sleep(3); write(fd[1],hello pipe,strlen(hello pipe)); printf(父进程:%d完成写入\n, getpid()); //通信完成 应该关闭写端 close(fd[0]); //等待子进程退出 wait(NULL); } return 0; }3、无名管道读写的特点1、默认用read函数从管道中读数据是阻塞的。2、调用write函数向管道里写数据当缓冲区已满时write也会阻塞。3、通信过程中读端口全部关闭后写进程向管道内写数据时写进程会收 到SIGPIPE信号退出。4、无名管道ps -A | grep bash实现#include stdio.h #include unistd.h #include string.h #include sys/wait.h int main(int argc, char const *argv[]) { //创建一个无名管道 int fd[2]; pipe(fd); //创建两个子进程 int i0; for(i0;i2;i) { pid_t pidfork(); if(pid0) break;//防止子进程继续创建子进程 } if(i0)//子进程1 { //ps ‐A 写端 close(fd[0]); //1作为fd[1]的副本 dup2(fd[1],1); //执行ps ‐A execlp(ps,ps,-A,NULL); _exit(-1); } else if(i1)//子进程2 { //grep bash 读端 close(fd[1]); //0作为fd[0]的副本 dup2(fd[0],0); //执行grep bash execlp(grep,grep,bash,NULL); } if(i2) //父进程 { //关闭管道读写端 close(fd[0]); close(fd[1]); while(1) { pid_t pidwaitpid(-1,NULL,WNOHANG); if(pid0) printf(子进程%d退出了\n, pid); else if(pid0) continue; else if(pid0) break; } } return 0; }三、有名管道FIFO命名管道1、概述主要用于没有血缘关系的进程间通信。特点:半双工数据在同一时刻只能在一个方向上流动。写入FIFO中的数据遵循先入先出的规则。FIFO所传送的数据是无格式的这要求FIFO的读出方与写入方必须事先 约定好数据的格式如多少字节算一个消息等。FIFO在文件系统中作为一个特殊的文件而存在但FIFO中的内容却存放在内存中。管道在内存中对应一个缓冲区。不同的系统其大小不一定相同。从FIFO读数据是一次性操作数据一旦被读它就从FIFO中被抛弃释 放空间以便写更多的数据。当使用FIFO的进程退出后FIFO文件将继续保存在文件系统中以便以后使用。FIFO有名字不相关的进程可以通过打开命名管道进 行通信(重要2、创建有名管道 mkfifoFIFO文件的创建#includesys/type.h#includesys/stat.hint mkfifo( const char *pathname, mode_t mode);参数pathnameFIFO的路径名文件名。modemode_t类型的权限描述符。返回值 成功返回 0 失败如果文件已经存在则会出错且返回-1fifo_write.c:#include stdio.h #include sys/types.h #include sys/stat.h #include sys/fcntl.h #include unistd.h #include string.h int main() { //创建有名管道(确保两个进程识别相同目录) mkfifo(my_fifo,0666); //open以写的方式的打开 有名管道(阻塞 到 对方 以读的方式打开) int fpopen(my_fifo,O_WRONLY); if(fp0) { perror(open); return 0; } printf(写端open成功\n); while(1) { //获取键盘输入 unsigned char buf[128]; printf(请输入需要发送的数据:); fgets(buf,sizeof(buf),stdin); buf[strlen(buf)-1]0; //发送数据 write(fp,buf,sizeof(buf)); //退出循环 if(strcmp(buf,Bye)0) break; } close(fp); }fifo.read.c#include stdio.h #include sys/types.h #include sys/stat.h #include sys/fcntl.h #include unistd.h #include string.h int main() { //创建有名管道(确保两个进程识别相同目录) mkfifo(my_fifo,0666); //open以读的方式的打开 有名管道(阻塞 到 对方 以写的方式打开) int fpopen(my_fifo,O_RDONLY); if(fp0) { perror(open); return 0; } printf(读端open成功\n); //循环的读取数据 while(1) { //接收数据 unsigned char buf[128]; read(fp,buf,sizeof(buf)); printf(收到数据:%s\n, buf); //退出循环 if(strcmp(buf,Bye)0) break; } close(fp); }3、有名管道读写的特点阻塞方式打开管道1、open以只读方式打开FIFO时要阻塞到某个进程为写而打开此FIFO2、open以只写方式打开FIFO时要阻塞到某个进程为读而打开此FIFO。3、open以只读、只写方式打开FIFO时会阻塞调用read函数从FIFO里读数据时read也会阻塞。4、通信过程中若写进程先退出了则调用read函数从FIFO里读数据时不阻塞若写进程又 重新运行则调用read函数从FIFO里读数据时又恢复阻塞。5、通信过程中读进程退出后写进程向命名管道内写数据时写进程也会收到 SIGPIPE信号退出。6、调用write函数向FIFO里写数据当缓冲区已满时write也会阻塞。非阻塞方式打开管道1、先以只读方式打开如果没有进程已经为写而打开一个FIFO, 只读open成功并且open不阻塞。2、先以只写方式打开如果没有进程已经为读而打开一个FIFO只写open 将出错返回-1。3、read、write读写命名管道中读数据时不阻塞。4、通信过程中读进程退出后写进程向命名管道内写数据时写进程也会收到 SIGPIPE信号退出。注意open函数以可读可写方式打开FIFO文件时的特点1、open不阻塞。2、调用read函数从FIFO里读数据时read会阻塞。3、调用write函数向FIFO里写数据当缓冲区已满时write也会阻塞
延伸阅读

更多相关文章

2026/9/11 15:15:05

端到端智驾算法:文章导航页

零、端到端任务概述 一、两段式端到端算法 https://blog.csdn.net/weixin_54853916/article/details/163129567?spm1011.2124.3001.6209 二、一段式端到端算法 三、SD信息应用 四、自动驾驶中强化学习算法介绍 五、端到端轨迹输出的优化 六、时空联合规划

2026/9/10 5:06:45

终极指南:3分钟掌握BetterNCM插件管理器完整安装教程

终极指南:3分钟掌握BetterNCM插件管理器完整安装教程 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 你是否厌倦了网易云音乐功能的局限性?想要解锁更多个性化体…

2026/9/7 9:20:16

WorkshopDL:无需Steam客户端的742+款游戏模组下载神器

WorkshopDL:无需Steam客户端的742款游戏模组下载神器 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 还在为Steam创意工坊的丰富模组而心动,却因为游戏不…

2026/9/11 15:12:20

GESP四级C++考试判断题解析与应试技巧

1. GESP四级C考试判断题解析指南作为国内权威的青少年编程能力认证,GESP(Grade Examination of Software Programming)考试近年来受到越来越多学生和家长的关注。2025年6月这次四级C考试的第二部分判断题(1-10题)主要考…

2026/9/11 15:12:20

C语言编程入门:从环境搭建到项目实战

1. 为什么C语言依然是编程入门的首选? 2003年我在大学计算机实验室第一次接触C语言时,那台老旧的CRT显示器上闪烁的"Hello World"让我记忆犹新。二十年过去了,尽管编程语言层出不穷,C语言依然是计算机教育的基石。根据2…

2026/9/11 15:12:20

虚拟电厂鲁棒优化调度:MATLAB实现与工程实践

1. 虚拟电厂调度中的鲁棒优化实践去年参与某区域虚拟电厂项目时,光伏出力预测偏差和负荷突变问题让我们吃尽苦头。传统确定性优化在实测中调度失败率高达34%,直到引入鲁棒优化方法后才将系统容错能力提升至设计指标。今天就把项目中验证有效的MATLAB实现…

2026/9/10 16:39:38

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/10 11:16:38

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 12:32:02

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/10 15:19:50

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/10 15:49:53

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码