发布时间:2026/7/24 20:19:29
【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/7/24 20:19:29

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

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

2026/7/24 20:19:29

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

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

2026/7/24 20:14:29

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

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

2026/7/24 21:44:36

为什么别人的代码能秒跑,你却要配3小时环境

为什么别人的代码能秒跑,你却要配3小时环境 昨天群里有个人问:"大佬们,我下载了个开源项目,跑不起来怎么办?" 然后贴了二十几张报错截图,涵盖了node版本不对、python依赖装不上、数据库连不上、端…

2026/7/24 21:44:36

手把手教你学pcie-第二种:MMIO 空间(Memory-Mapped I/O)

目录 五、第二种:MMIO 空间(Memory-Mapped I/O) 1️⃣ MMIO 是什么? 2️⃣ MMIO 和配置空间的本质区别 3️⃣ MMIO 从哪里来? 4️⃣ CPU 眼中的 MMIO 5️⃣ Linux 驱动如何访问 MMIO? ✅ 第一步&…

2026/7/24 21:44:36

纳新 FPGA逻辑开发工程师

FPGA逻辑开发工程师 薪资待遇:12K-25K/月,具体薪资面谈一、岗位职责: 1、 负责FPGA逻辑设计、仿真、综合、布局布线等开发工作; 2、 根据项目需求,进行FPGA器件选型和配置; 3、 编写和维护相关技术文档…

2026/7/24 21:39:35

AI副业合法变现路径图(2024最新监管白皮书实操版)

更多请点击: https://intelliparadigm.com 第一章:AI副业合法变现的底层合规逻辑 AI副业的可持续性不取决于模型有多强大,而在于其商业行为是否嵌入法定权利义务框架之中。合法变现的核心,是将技术输出转化为受法律承认的“可交易…

2026/7/23 12:54:51

Unity与Python本地通信:基于Flask的跨语言数据交换实战

1. 项目概述:为什么我们需要一个本地通信服务器?在游戏开发、数字孪生、仿真训练等众多领域,Unity作为强大的实时3D内容创作平台,其核心逻辑通常由C#驱动。然而,当我们需要进行复杂的数据分析、机器学习推理、科学计算…

2026/7/24 0:03:10

不同品牌斜齿行星减速机如何替换?以PX与PAG系列为例

不同品牌斜齿行星减速机如何替换?以 PX 与 PAG 系列为例 一、系列对应不等于型号直接互换 PX 与 PAG 都属于斜齿、方法兰、输出轴式精密行星减速机,结构形式和应用方向具有对应关系。 原设备使用PX系列时,可以优先从PAG系列中寻找替换型号。但…

2026/7/24 0:03:10

jdk8 把list 扁平化成String 多个以逗号分隔

在 JDK 8 中&#xff0c;将 List 扁平化为以逗号分隔的 String&#xff0c;有几种非常简洁且高效的方法。&#x1f680; 推荐方案&#xff1a;使用 Collectors.joining()这是最标准的 Java 8 写法&#xff0c;适用于 List<String>。javaimport java.util.stream.Collecto…

2026/7/24 0:03:10

java 两个 long id 怎么合并成一个long id 并且不重复

“把两个 Long ID 合并成一个唯一的 Long ID&#xff0c;且保证不重复”这个需求&#xff0c;在 Java 里直接做数学上的“完美合并”是不可能的。因为两个 Long&#xff08;各 64 位&#xff09;要合并成一个 Long&#xff08;64 位&#xff09;&#xff0c;在信息论上是有损压…

2026/7/23 23:42:43

3个高效策略:快速掌握Axure中文界面配置

3个高效策略&#xff1a;快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…