【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.mzph.cn/pingmian/31742.shtml

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

相关文章

Java8使用Stream流实现List列表查询、统计、排序、分组、合并

Java8使用Stream流实现List列表查询、统计、排序以及分组 目录 一、查询方法1.1 forEach1.2 filter(T -> boolean)1.3 filterAny() 和 filterFirst()1.4 map(T -> R) 和 flatMap(T -> Stream)1.5 distinct()1.6 limit(long n) 和 skip(long n) 二、判断方法2.1 anyMa…

容器之按钮盒构件演示

代码; #include <gtk-2.0/gtk/gtk.h> #include <glib-2.0/glib.h> #include <gtk-2.0/gdk/gdkkeysyms.h> #include <stdio.h>int main(int argc, char *argv[]) {gtk_init(&argc, &argv);GtkWidget *window;window gtk_window_new(GTK_WINDO…

xargs 传参

xargs的默认命令是 echo&#xff0c;空格是默认定界符。这意味着通过管道传递给 xargs的输入将会包含换行和空白&#xff0c;不过通过 xargs 的处理&#xff0c;换行和空白将被空格取代。xargs是构建单行命令的重要组件之一。 xargs -n1 // 一次输出一个参数到一行&#xf…

Python学习笔记16:进阶篇(五)异常处理

异常 在编程中&#xff0c;异常是指程序运行过程中发生的意外事件&#xff0c;这些事件通常中断了正常的指令流程。它们可能是由于错误的输入数据、资源不足、非法操作或其他未预料到的情况引起的。Python中&#xff0c;当遇到这类情况时&#xff0c;会抛出一个异常对象&#…

最详细的Selenium+Pytest自动化测试框架实战

前言 selenium自动化 pytest测试框架 本章你需要 一定的python基础——至少明白类与对象&#xff0c;封装继承 一定的selenium基础——本篇不讲selenium&#xff0c; 测试框架简介 测试框架有什么优点呢&#xff1a; 代码复用率高&#xff0c;如果不使用框架的话&#xff…

2004年-2022年 全国31省市场分割指数数据

市场分割指数在经济学领域是一个关键的概念&#xff0c;特别是在评估不同区域市场一体化水平时。陆铭等学者深入研究了市场分割问题&#xff0c;并对市场分割指数给出了定义&#xff1a;它是一个衡量在相同时间点不同区域或同一区域在不同时间点的某类商品相对价格差异的指标。…

几种常见的滤波器样式

IIR Peaking Filter IIR LowShelf Filter IIR HighShelf Filter 4. IIR LowPassFilter 5. IIR HighPass Filter FIR PeakingFilter FIR LowShelf Filter 8. FIR HighShelf Filter 8. FIR LowPass Filter 10. FIR HighPass Filter

OpenHarmony-HDF驱动框架介绍及加载过程分析

前言 HarmonyOS面向万物互联时代&#xff0c;而万物互联涉及到了大量的硬件设备&#xff0c;这些硬件的离散度很高&#xff0c;它们的性能差异与配置差异都很大&#xff0c;所以这要求使用一个更灵活、功能更强大、能耗更低的驱动框架。OpenHarmony系统HDF驱动框架采用C语言面…

【Kafka】Kafka Broker工作流程、节点服役与退役、副本、文件存储、高效读写数据-08

【Kafka】Kafka Broker工作流程、节点服役与退役、副本、文件存储、高效读写数据 1. Kafka Broker 工作流程1.1 Zookeeper 存储的 Kafka 信息1.2 Kafka Broker总体工作流程1.2.1 Controller介绍 1.3 Broker 重要参数 2. 节点服役与退役3. Kafka副本 1. Kafka Broker 工作流程 …

GUI Guider(V1.7.2) 设计UI在嵌入式系统上的应用(N32G45XVL-STB)

目录 概述 1 使用GUI Guider 设计UI 1.1 创建页面 1.2 页面切换事件实现 1.3 生成代码和仿真 1.3.1 生成和编译代码 1.3.2 仿真UI 2 GUI Guider生成的代码结构 2.1 代码结构介绍 2.2 Project目录下的文件 3 板卡上移植UI 3.1 加载代码至工程目录 3.2 主函数中调…

【环境变量问题:计算机删除环境变量的恢复方法;此环境变量太大。此对话框允许将值设置为最长2047个字符】

不小心误删了win10系统环境变量可以试试下文方法恢复。 本方法针对修改环境变量未重启的用户可以使用&#xff0c;如果修改环境变量&#xff0c;然后还重启了&#xff0c;只能说重新来。 方法一&#xff1a;使用命令提示符恢复 被修改的系统Path只是同步到了注册表中&#x…

2024软考系规考前复习20问!看看你能答上来多少

今天给大家整理了——2024系统规划与管理师考前20问&#xff0c;这是一份很重要的软考备考必看干货&#xff0c;包含很多核心知识点。有PDF版&#xff0c;可打印下来&#xff0c;过完一遍教材后&#xff0c;来刷一刷、背一背&#xff0c;说不定可以帮你拿下不少分。 第1问- 信息…

2024.6.23周报

目录 摘要 ABSTRACT 一、文献阅读 一、题目 二、摘要 三、网络架构 四、创新点 五、文章解读 1、Introduction 2、Method 3、实验 4、结论 二、代码实验 总结 摘要 本周阅读了一篇题目为NAS-PINN: NEURAL ARCHITECTURE SEARCH-GUIDED PHYSICS-INFORMED NEURAL N…

解决电脑关机难题:电脑关不了机的原因以及方法

在使用电脑的日常生活中&#xff0c;有时会遇到一些烦人的问题&#xff0c;其中之一就是电脑关不了机。当您尝试关闭电脑时&#xff0c;它可能会停留在某个界面&#xff0c;或者根本不响应关机指令。这种情况不仅令人困惑&#xff0c;还可能导致数据丢失或系统损坏。 在本文中…

DS:堆的应用——两种算法和TOP-K问题

欢迎来到Harper.Lee的学习世界&#xff01;博主主页传送门&#xff1a;Harper.Lee的博客主页想要一起进步的uu可以来后台找我哦&#xff01; 一、堆的排序 1.1 向上调整——建小堆 1.1.1 代码实现 //时间复杂度&#xff1a;O(N*logN) //空间复杂度&#xff1a;O(logN) for (…

计算机网络知识点汇总

计算机网络知识点汇总 第1章计算机网络体系结构 1.1 计算机网络概述 1.1.1 计算机网络的概念 ​ 计算机网络是由若干个结点(node)和连接这些结点的链路(link)组成。网络中的结点可以是就三级、集线器、交换机、或者路由器等&#xff0c;网络之间通过路由器进行互联&#xf…

Nodejs 第七十九章(Kafka进阶)

kafka前置知识在上一章讲过了 不再复述 kafka进阶 1. server.properties配置文件 server.properties是Kafka服务器的配置文件&#xff0c;它用于配置Kafka服务的各个方面&#xff0c;包括网络设置、日志存储、消息保留策略、安全认证 #broker的全局唯一编号&#xff0c;不能…

MySQL数据库初体验+数据库管理(其一)

【1】 操作系统介绍&#xff1a; Linux操作系统有 RedHat CentOS Debian Ubuntu OpenSUSE 信创标准 国产系统 &#xff1a; 华为&#xff08;欧拉&#xff09; 阿里&#xff08;龙蜥&#xff09; 腾讯 &#xff08;tencentOS&#xff09; 麒麟&#xf…

【日记】梦到兄长要给鳄鱼换牙齿……(421 字)

正文 今天中午睡了一个小时多一点&#xff0c;做了一个很奇怪的梦。梦见兄长要给一条鳄鱼换牙齿&#xff0c;还说早上不好操作&#xff0c;要三天之后的中午或晚上&#xff0c;颇有一种翻黄历寻个良辰吉日之感。但我没那样大的耐性&#xff0c;便捏住鳄鱼的嘴&#xff0c;左摔右…

实战18:基于tkinter+jupyter notebook开发的情感分析系统

项目演示: 完整代码: import pandas as pd import numpy as np from collections import Counter import re import jieba from tqdm import tqdm from sklearn.metrics import roc_curve, auc import joblib import gensim from sklearn.svm import SVC from gensim.mode…