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

目录

一、文件描述符复制

1、dup函数(复制文件描述符)

​编辑 2、dup2函数(复制文件描述符)

​编辑 二、无名管道pipe

1、概述 

2、无名管道的创建

 3、无名管道读写的特点

 4、无名管道ps -A | grep bash实现

 三、有名管道FIFO(命名管道)

1、概述 

2、创建有名管道 mkfifo

3、有名管道读写的特点


一、文件描述符复制

        让新的文件描述符 指向 旧的文件描述符。(新旧文件描述符指向同一个文件) 使用的函数dup、dup2。

1、dup函数(复制文件描述符)

#include<unistd.h>

int dup(int oldfd);

        dup函数的功能:从系统中寻找最小可用的文件描述符 作为oldfd的副本。 新文件描述符 通过dup的返回值返回。

 2、dup2函数(复制文件描述符)

        #include<unistd.h>

        int dup2(int oldfd, int newfd);  

dup2的功能:将newfd作为oldfd的副本。 如果newfd事先存在 dup2会先close(newfd),然后将newfd作为oldfd的副本。 

 二、无名管道pipe

1、概述 

         管道(pipe)又称无名管道。 无名管道是一种特殊类型的文件,在应用层体现为 两个打开的文件描述符(读端和写端)。

管道的特点:

  1. 半双工,数据在同一时刻只能在一个方向上流动。
  2. 数据只能从管道的一端写入,从另一端读出
  3. 写入管道中的数据遵循先入先出的规则。
  4. 管道所传送的数据是无格式的,这要求管道的读出方与写入方必须事先约定好数据 的格式, 如多少字节算一个消息等。
  5. 管道不是普通的文件,不属于某个文件系统,其只存在于内存
  6. 管道在内存中对应一个缓冲区。不同的系统其大小不一定相同。
  7. 从管道读数据是一次性操作,数据一旦被读走,它就从管道中被抛弃,释放空间以便写更多的数据。
  8. 管道没有名字,只能在具有公共祖先的进程之间使用 

2、无名管道的创建

        #include<unistd.h>

        int 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 pid=fork();if(pid==0)//子进程{//子进程的写端无意义(可以事先关闭)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(pid>0) //父进程{//父进程的读端无意义(可以事先关闭)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 i=0; for(i=0;i<2;i++){pid_t pid=fork();if(pid==0)break;//防止子进程继续创建子进程}if(i==0)//子进程1{//ps ‐A 写端close(fd[0]);//1作为fd[1]的副本dup2(fd[1],1);//执行ps ‐Aexeclp("ps","ps","-A",NULL);_exit(-1);}else if(i==1)//子进程2{//grep bash 读端close(fd[1]);//0作为fd[0]的副本dup2(fd[0],0);//执行grep bashexeclp("grep","grep","bash",NULL);}if(i==2) //父进程{//关闭管道读写端close(fd[0]);close(fd[1]);while(1){pid_t pid=waitpid(-1,NULL,WNOHANG);if(pid>0)printf("子进程%d退出了\n", pid);else if(pid==0)continue;else if(pid<0)break;}}return 0;
}

 三、有名管道FIFO(命名管道)

1、概述 

         主要用于没有血缘关系的进程间通信。

 

 特点:

  1. 半双工,数据在同一时刻只能在一个方向上流动。
  2. 写入FIFO中的数据遵循先入先出的规则。
  3. FIFO所传送的数据是无格式的,这要求FIFO的读出方与写入方必须事先 约定好数据的格式,如多少字节算一个消息等。
  4. FIFO在文件系统中作为一个特殊的文件而存在,但FIFO中的内容存放在内存中。
  5. 管道在内存中对应一个缓冲区。不同的系统其大小不一定相同
  6. 从FIFO读数据是一次性操作,数据一旦被读,它就从FIFO中被抛弃,释 放空间以便写更多的数据。
  7. 当使用FIFO的进程退出后,FIFO文件将继续保存在文件系统中以便以后使用。
  8. FIFO有名字不相关的进程可以通过打开命名管道进 行通信(重要)

2、创建有名管道 mkfifo

FIFO文件的创建

        #include<sys/type.h>

        #include<sys/stat.h>

        int mkfifo( const char *pathname, mode_t mode);

参数:

pathname:FIFO的路径名+文件名。

mode:mode_t类型的权限描述符。

返回值: 成功:返回 0 失败:如果文件已经存在,则会出错且返回-1

 fifo_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 fp=open("my_fifo",O_WRONLY);if(fp<0){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 fp=open("my_fifo",O_RDONLY);if(fp<0){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时,要阻塞到某个进程为而打开此FIFO

2、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也会阻塞

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/355904.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习Week17——优化器对比实验

文章目录 深度学习Week17——优化器对比实验 一、前言 二、我的环境 三、前期工作 1、配置环境 2、导入数据 2.1 加载数据 2.2 检查数据 2.3 配置数据集 2.4 数据可视化 四、构建模型 五、训练模型 1、将其嵌入model中 2、在Dataset数据集中进行数据增强 六、模型评估 1、Accur…

让我来告诉初学者到底什么叫嵌入式系统?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;我们在刚刚开始学习电子学…

噪声-降噪引脚如何提高系统性能

由于LDO是电子器件&#xff0c;因此它们会自行产生一定量的噪声。选择低噪声LDO并采取措施来降低内部噪声对于生成不会影响系统性能的清洁电源轨而言不可或缺。 识别噪声 理想的 LDO 会生成没有交流元件的电压轨。遗憾的是&#xff0c;LDO 会像其他电子器件一样自行产生噪声。…

Java数据类型与运算符

1. 变量和类型 变量指的是程序运行时可变的量&#xff0c;相当于开辟一块空间来保存一些数据。 类型则是对变量的种类进行了划分&#xff0c;不同类型的变量具有不同的特性。 1.1 整型变量&#xff08;重点&#xff09; 基本语法格式&#xff1a; int 变量名 初始值;代码示…

大语言模型-Transformer

目录 1.概述 2.作用 3.诞生背景 4.历史版本 5.优缺点 5.1.优点 5.2.缺点 6.如何使用 7.应用场景 7.1.十大应用场景 7.2.聊天机器人 8.Python示例 9.总结 1.概述 大语言模型-Transformer是一种基于自注意力机制&#xff08;self-attention&#xff09;的深度学习…

开发中遇到的错误 - @SpringBootTest 注解爆红

我在使用 SpringBootTest 注解的时候爆红了&#xff0c;ait 回车也导不了包&#xff0c;后面发现是因为没有加依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId>…

云计算技术高速发展,优势凸显

云计算是一种分布式计算技术&#xff0c;其特点是通过网络“云”将巨大的数据计算处理程序分解成无数个小程序&#xff0c;并通过多部服务器组成的系统进行处理和分析这些小程序&#xff0c;最后将结果返回给用户。它融合了分布式计算、效用计算、负载均衡、并行计算、网络存储…

MEME使用-motif分析(生物信息学工具-24)

01 背景 Motif分析是一种在生物信息学和计算生物学中广泛应用的技术&#xff0c;用于识别DNA、RNA或蛋白质序列中具有生物学功能的短保守序列模式&#xff08;motif&#xff09;。这些motif通常与特定的生物学功能相关&#xff0c;如DNA中的转录因子结合位点、RNA中的剪接位点…

C++ 计算凸包点的最小旋转矩形

RotateRect.h #include <vector>/** * brief 计算点集最小旋转外接矩形 */ class RotateRect { public:enum { CALIPERS_MAXHEIGHT 0, CALIPERS_MINAREARECT 1, CALIPERS_MAXDIST 2 };struct Point {float x, y;};using Points std::vector<Point>;struct Size…

微服务SpringCloud ES分布式全文搜索引擎简介 下载安装及简单操作入门

Elasticsearch ES简介 Elasticsearch&#xff08;简称ES&#xff09;是一个开源的分布式搜索和分析引擎&#xff0c;常用于全文搜索、日志存储和分析等场景。它构建在Apache Lucene搜索引擎库之上&#xff0c;提供了一个分布式的多租户能力&#xff0c;支持大规模的数据处理。…

网络编程5----初识http

1.1 请求和响应的格式 http协议和前边学过的传输层、网络层协议不同&#xff0c;它是“一问一答”形式的&#xff0c;所以要分为请求和响应两部分看待&#xff0c;同时&#xff0c;请求和响应的格式是不同的&#xff0c;我们来具体介绍一下。 1.1.1 请求 在介绍请求之前&…

将自己md文件发布到自己的博客园实现文件的持久化存储

上传markdown文件到博客园 目录 【0】需求原因【1】功能【2】环境【最佳实践测试】 &#xff08;1&#xff09;查看 Typora 设置&#xff08;2&#xff09;配置 pycnblog 配置文件 config.yaml&#xff08;3&#xff09;运行 pycnblog 中的文件 cnblog_markdown.cmd&#xff0…

自杀行为的神经生物学认识

自杀行为的神经生物学认识 编译 李升伟 隐藏在自杀行为背后的大脑生化机制正引领人类对自杀的认识从黑暗步入光明。科学家希望未来这些机制能带来更好的治疗和预防策略。 基斯 • 范希林根&#xff08;Cornelis Van Heeringen&#xff09;第一次遇见瓦莱丽&#xff08; Va…

Java用文件流mask文本文件某些特定字段

思路 在Java中&#xff0c;如果你想要掩码&#xff08;mask&#xff09;文本文件中的某些特定字段&#xff0c;你可以按照以下步骤进行&#xff1a; 读取文本文件内容。找到并识别需要掩码的字段。用特定的掩码字符&#xff08;如星号*&#xff09;替换这些字段。将修改后的内…

Leetcode Hot100之双指针

1. 移动零 题目描述 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。解题思路 双指针遍历一遍即可解决: 我们定义了两个指针 i 和 j&#xf…

浏览器(Browser):轻量级浏览器,高效浏览新体验

在可的哥桌面&#xff08;Codigger Desktop&#xff09;&#xff0c;我们始终秉持创新精神&#xff0c;致力于提供卓越的用户体验。如今&#xff0c;我们激动地宣布一项全新功能的发布——轻量级浏览器Browser。这款浏览器的推出&#xff0c;正是我们对用户体验追求的再次体现&…

使用自签名 TLS 将 Dremio 连接到 MinIO

Dremio 是一个开源的分布式分析引擎&#xff0c;为数据探索、转换和协作提供简单的自助服务界面。Dremio 的架构建立在 Apache Arrow&#xff08;一种高性能列式内存格式&#xff09;之上&#xff0c;并利用 Parquet 文件格式实现高效存储。有关 Dremio 的更多信息&#xff0c;…

从艳彩山水到艳彩艺术 薛永年:郭泰来艳彩艺术填补了中国美术史的空白

薛永年先生 自6月12日开展以来&#xff0c;郭泰来现代艺术大展杭州如火如荼地进行着&#xff0c;吸引了众多艺术爱好者和专业人士前往。毫不夸张地说&#xff0c;总统和清洁工人都能在他的作品中找到自己心中的那一块共振带并与之产生强烈的共鸣&#xff0c;这便是郭泰来先生的…

目标跟踪算法(bytetrack)-tensorrt部署教程

一、本机安装python环境 conda create -n bytetrace_env python=3.8 activate bytetrace_env conda install pytorch torchvision cudatoolkit=10.1 -c检测GPU是否可用,不可用不行 import torch print(torch.cuda.is_available())安装bytetrack git clone https://github.c…

0.15元1.5Mhz-1.3A同步整流BUCK降压DCDC芯片MT3410(MT3410LB)

前言 国产同步整流DCDC&#xff0c;参考价格约0.15元。 特征 高效率&#xff1a;高达 96% 1.5MHz恒定频率操作 1.3A 输出电流 无需肖特基二极管 2.3V至7V输入电压范围 输出电压低至 0.6V PFM 模式可在轻负载下实现高效率 压差操作中的100%占空比 低静态电流&#xff1a;35μ…