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

发布时间:2026/11/6 0:53:27

【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/11/2 18:36:11

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

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

2026/11/2 23:05:48

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

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

2026/11/3 15:48:57

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

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

2026/11/5 16:51:33

EasyU优启通PE维护盘实战指南:制作、启动与核心操作全解析

1. 为什么一个PE维护盘值得单独拿出来聊装系统、修引导、救数据、清病毒,这些活儿但凡干过几次的人都知道,真正决定效率的往往不是你手速多快,而是手边那套PE环境靠不靠谱。EasyU(圈内习惯叫优启通)就是在这个场景下被…

2026/11/5 16:26:13

Rust原来很简单二:所有权系统

Part 2 核心篇 —— 所有权系统 本篇覆盖 第 6 ~ 10 章:所有权、借用与引用、生命周期、字符串与切片、内存模型。 ⚠️ 这是全书最重要的一篇。 把它吃透,Rust 从此“很简单”;跳过它,你会处处碰壁。请慢下来,动手敲每一段代码。 第 6 章 所有权:Rust 的第一性原理 6…

2026/11/5 15:00:49

基于Hadoop+Spark的民宿智能推荐系统设计与实现

1. 项目概述:大数据时代的民宿智能推荐这个毕业设计项目融合了当前大数据领域最主流的技术栈,构建了一个完整的民宿推荐系统解决方案。作为一名长期从事大数据系统开发的工程师,我认为这个选题非常贴合实际应用场景——随着旅游业的复苏和共享…

2026/11/5 14:10:30

ADS122U04IPWR+STM32F427ZI工业级温度测量信号链设计

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

2026/11/5 14:10:30

UART接口24位ADC搭配RS485,解决远距离温度监控难题

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

2026/11/5 14:10:30

UART接口24位ADC搭配PIC18F46K22的RTD与热电偶测温实践

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

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

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

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

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

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

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

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