Linux管道

article/2025/9/23 2:56:00

目录

1.管道概念

2.管道分类

        1.匿名管道

        1.基本实现与概念

        2.站在文件描述符角度-深度理解管道

        3.站在内核角度-管道本质

        4.管道读写规则

        5.管道属性设置与阻塞验证       

         6.管道特点(匿名)

        2.命名管道

        1.创建一个命名管道

        2.命名管道的打开规则 

 3.匿名管道与命名管道的区别


1.管道概念

        管道是Linux中的最古老的通信方式;

        我们把一个进程链接到另一个进程的一个数据流称为一个"管道";

2.管道分类

        1.匿名管道

        1.基本实现与概念

        头文件: #include <unistd.h>

        功能:创建一无名管道原型int pipe(int fd[2]);

        参数fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端返回值:成功返回0,失败返回错误代码

         通常用fork函数来共享管道;接下来我们来实现一下匿名管道的基本读写的实现:

                                                                不关闭描述符

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <wait.h>int main(){int fd[2];int ret=pipe(fd);if(ret<0){perror("pipe");return 0;}pid_t pid=fork();if(pid<0){perror("fork");return 0;}else if(pid==0){//child//子进程进行接受char buf_read[1024]={0};read(fd[0],buf_read,sizeof(buf_read)-1);printf("The content is :%s\n",buf_read);}else{//father//父进程发送数据char buf_write[]="success!";write(fd[1],buf_write,strlen(buf_write));wait(NULL);}return 0;
}

                                                                运行结果

        我们可以看出来在父进程向管道写入信息,在子进程读取管道信息. 

                                                          关闭描述符

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <wait.h>int main(){int fd[2];int ret=pipe(fd);if(ret<0){perror("pipe");return 0;}pid_t pid=fork();if(pid<0){perror("fork");return 0;}else if(pid==0){//child//子进程进行接受close(fd[1]);char buf_read[1024]={0};read(fd[0],buf_read,sizeof(buf_read)-1);printf("The content is :%s\n",buf_read);}else{//father//父进程发送数据close(fd[0]);char buf_write[]="success!";write(fd[1],buf_write,strlen(buf_write));wait(NULL);}return 0;
}

                                                        运行结果 

                我们可以看出依旧可以进行读写~原因是什么呢?

        2.站在文件描述符角度-深度理解管道

 

        首先父进程创建管道,系统默认打开三个文件:标准输入,标准输出,和标准错误;创建管道则有fd[0],fd[1];分别表示管道的读端和写端;

         然后父进程创建子进程,子进程拷贝父进程,也拷贝了管道信息;所以父子进程共享管道;

         父进程关闭读端,子进程关闭写端,但是管道是共享的,依旧可以进行信息交互;

        3.站在内核角度-管道本质

 看待管道,就如同看待文件一样!管道的使用和文件一致,迎合了“Linux一切皆文件思想”。

        4.管道读写规则

        当没有数据可读时O_NONBLOCK disable:read调用阻塞,即进程暂停执行,一直等到有数据来到为止。O_NONBLOCK enable:read调用返回-1,errno值为EAGAIN。

        当管道满的时候O_NONBLOCK disable: write调用阻塞,直到有进程读走数据O_NONBLOCK enable:调用返回-1,errno值为EAGAIN如果所有管道写端对应的文件描述符被关闭,则read返回0   

        如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPE,进而可能导致write进程退出

        当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。

        当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。

        5.管道属性设置与阻塞验证       

        fcntl函数原型:

#include<unistd.h>
#include<fcntl.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd ,struct flock* lock);

 (1)F_DUPFD

与dup函数功能一样,复制由fd指向的文件描述符,调用成功后返回新的文件描述符,与旧的文件描述符共同指向同一个文件。

(2)F_GETFD

读取文件描述符close-on-exec标志

(3)F_SETFD

将文件描述符close-on-exec标志设置为第三个参数arg的最后一位

(4)F_GETFL

获取文件打开方式的标志,标志值含义与open调用一致

(5)F_SETF

设置文件打开方式为arg指定方式

设置读端为非阻塞:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>int main(){int fd[2];int ret=pipe(fd);if(ret<0){perror("pipe");return 0;}pid_t pid=fork();if(pid<0){perror("fork");return 0;}else if(pid==0){//child //关闭写端//设置读端为非阻塞属性//读close(fd[1]);int flag=fcntl(fd[0],F_GETFL);fcntl(fd[0],F_SETFL,flag|O_NONBLOCK);char buf_read[1024]={0};ssize_t read_size=read(fd[0],buf_read,sizeof(buf_read)-1);printf("read_size:%ld\n",read_size);perror("read");}else{//father//关闭读端//写关闭/不关闭close(fd[0]);close(fd[1]);}while(1){sleep(1);}return 0;
}

                                                                        运行结果为:

 设置写端非阻塞:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>int main(){int fd[2];int ret=pipe(fd);if(ret<0){perror("pipe");return 0;}pid_t pid=fork();if(pid<0){perror("fork");return 0;}else if(pid==0){//child//关闭子进程读端//设置子进程写段为非阻塞//子进程写close(fd[0]);int flag=fcntl(fd[1],F_GETFL);fcntl(fd[1],F_SETFL,flag|O_NONBLOCK);ssize_t write_size;while(1){write_size=write(fd[1],"a",1);if(write_size<0){break;}}printf("write_size:%ld\n",write_size);}else{//father//关闭父进程写端//关闭父进程读端/不关闭close(fd[1]);//close(fd[0]);while(1){sleep(1);}}return 0;
}

                                                运行结果:

         6.管道特点(匿名)

        只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信;

        通常,一个管道由一个进程创建,然后该进程调用fork,此后父、子进程之间就可应用该管道。

        管道提供流式服务一般而言,进程退出,管道释放,所以管道的生命周期随进程一般而言,内核会对管道操作进行同步与互斥管道是半双工的;

        数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;

        2.命名管道

        管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。

        如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。

        命名管道是一种特殊类型的文件

        1.创建一个命名管道

$ mkfifo pipe1

执行结果: 

也可以程序创建

函数原型:

#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char *filename,mode_t mode);

                                        代码如下: 

#include <stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
int main(){mkfifo("pipe2",0664);return 0;
}

                                        运行结果

        2.命名管道的打开规则 

        如果当前打开操作是为读而打开FIFO时

        O_NONBLOCK disable:阻塞直到有相应进程为写而打开该FIFO

        O_NONBLOCK enable:立刻返回成功如果当前打开操作是为写而打开FIFO时

        O_NONBLOCK disable:阻塞直到有相应进程为读而打开该FIFO 

        O_NONBLOCK enable:立刻返回失败,错误码为ENXIO                

 3.匿名管道与命名管道的区别

        匿名管道由pipe函数创建并打开。

        命名管道由mkfifo函数创建,打开用openFIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义。


http://chatgpt.dhexx.cn/article/6n7GexOd.shtml

相关文章

linux中管道的概念,浅谈Linux管道

通过前面的学习&#xff0c;我们已经知道了怎样从文件重定向输入&#xff0c;以及重定向输出到文件。Shell 还有一种功能&#xff0c;就是可以将两个或者多个命令&#xff08;程序或者进程&#xff09;连接到一起&#xff0c;把一个命令的输出作为下一个命令的输入&#xff0c;…

linux管道举例理解

linux管道举例理解 一、管道的定义&#xff1a;“|”二、查找2.1统计当前目录下有多少个文件2.2查看当前目录下的前n&#xff08;3&#xff09;个文件2.3查看wang.txt文件包含i的字符行2.4查看内存使用情况2.5查询进程 三、更改 https://blog.csdn.net/hanhanwanghaha宝藏女孩 …

图解YUV格式

YUV格式有两大类&#xff1a;planar和packed。 对于planar的YUV格式&#xff0c;Y&#xff0c;U&#xff0c;V都是连续存放的&#xff0c;比如 YYYYUUUUVVVV 对于packed的YUV格式&#xff0c;每个像素点的Y,U,V是连续交替存储的。 RGB24&#xff0c;BGR24等等都是packed方式存…

走进音视频的世界——RGB与YUV格式

在图像的世界里&#xff0c;一般使用RGB作为存储格式。而在视频的世界里&#xff0c;一般使用YUV作为压缩存储格式。有时候面试官会问&#xff1a;为什么视频使用YUV来压缩存储&#xff0c;而不用RGB&#xff1f;YUV与RGB有什么区别&#xff0c;两者如何转换的&#xff1f;常见…

YUV格式像素

一幅彩色图像的基本要素是什么&#xff1f; 说白了&#xff0c;一幅图像包括的基本东西就是二进制数据&#xff0c;其容量大小实质即为二进制数据的多少。一幅1920x1080像素的YUV422的图像&#xff0c;大小是1920X1080X24147200&#xff08;十进制&#xff09;&#xff0c;也就…

查看YUV格式文件

RGB图片文件转换为YUV格式后&#xff0c;将YUV数据以二进制形式写到文件中&#xff0c;使用7yuv软件查看。 #include<iostream> #include<cstdio> #include<string> #include"opencv2/opencv.hpp"#include "libyuv/scale.h" #include &…

详解YUV数据格式

在博客园看到有大神写了一篇关于YUV图像格式的博客&#xff0c;图文分析很不错&#xff0c;这里就转载过来了。但排版有些乱&#xff0c;所以我就在原博文的基础上做了一些排版&#xff0c;修改 了一些错误。希望我们能共同进步。come on&#xff01;&#xff01; 一.YUV数据…

YUV格式的图片查看工具YUView 2.13

YUV格式的图片查看工具YUView 2.13 参考资料&#xff1a; Image to YUV (ffmpeg/ImageMagick) 这2个工具可用于音视频格式转换等处理 Image to YUV (ffmpeg/ImageMagick)_hushui的博客-CSDN博客 FFmpeg常用命令/参数 https://blog.csdn.net/weixin_36811328/article/details/88…

YUV文件格式

原文&#xff1a;YUV图像格式的博客 转&#xff1a;https://blog.csdn.net/armwind/article/details/52190123&#xff0c;文章不错特转载过来备忘 一.YUV数据格式的定义和采集方式 1&#xff09;YUV数据格式定义 YUV分为三个分量&#xff0c;“Y”表示明亮度&#xff08;Lu…

关于YUV格式的一些总结

关于YUV格式的一些总结 一、YUV和YCbCr1、定义2、区别和联系 二、不同的采样格式1、YUV4442、YUV4403、YUV4224、YUV4205、YUV4116、YUV410 三、YUV数据排列格式1、四种数据排列方式①Planar Format②Semi-Planar Format③Tiled Semi-Planar Format④Interleaved Format 2、常用…

音视频基础之YUV格式

1 YUV格式 1.1 YUV简介 YUV是一种颜色编码方式&#xff0c;类似于RGB颜色编码方式。YUV将亮度和色度分离&#xff0c;使用Y&#xff08;明亮度&#xff09;、U和V&#xff08;色度、浓度&#xff09;三个分量表示一个颜色。三个分量中UV分量只有颜色信息&#xff0c;如果图像只…

YUV格式与RGB格式

YUV与RGB格式介绍 一、RGB编码格式二、YUV编码格式YUV存储格式&#xff08;分类&#xff09;&#xff1a;YUV采样方式&#xff1a;常见的YUV格式 三、RGB与YUV转换公式 一、RGB编码格式 RGB图像具有三个通道 R、G、B&#xff0c;分别对应红、绿、蓝三个分量&#xff0c;由三个…

YUV数据格式介绍

YUV图像数据格式介绍 1.yuv格式的分类和介绍 2.YUV三个分量的代表含义 Y分量&#xff1a;表示明亮度&#xff08;Luma&#xff09;即灰度值 UY分量&#xff1a;表示色彩和饱和度即图片的颜色 U颜色代表 blue Y 颜色代表red YUV从形式上也可以用YCbCr 表示 3.常见的YUV格式…

YUV 格式详解-史上最全

YUV 格式详解 介绍分类标准具体分类I420&#xff08;属于 YUV 420 Plannar&#xff09;YV12&#xff08;属于 YUV 420 Plannar&#xff09;NV12&#xff08;属于 YUV 420 Semi-Planar&#xff09;NV21&#xff08;属于 YUV 420 Semi-Planar&#xff09;I422&#xff08;属于 YU…

YUV格式说明 YUYV JPEG

YUV420P&#xff0c;Y&#xff0c;U&#xff0c;V三个分量都是平面格式&#xff0c;分为 I420 和 YV12 。 I420 格式和 YV12 格式的不同处在U平面和V平面的位置不同。在I420格式中&#xff0c;U平面紧跟在Y平面之后&#xff0c;然后才是V平面&#xff08;即&#xff1a…

视频YUV格式详解

YUV三种存储格式 yuv按照存储格式的不同分为三类&#xff0c;平面&#xff0c;半平面和打包格式三种格式。其中I420就是一种平面格式。 平面的YUV格式&#xff0c;就是YUV三种分量分别单独的连续存储&#xff0c;不交叉。先连续存储所有像素点的Y&#xff0c;紧接着存储所有像…

YUV图像的常见格式(图示)

摘要 在研究android Camera2 API的时候&#xff0c;涉及到采集视频信息。其中&#xff0c;在采集视频的时候&#xff0c;可以设置多种类型格式的图像数据&#xff0c;其中一个就是yuv_420_888&#xff0c;如果需要进行编码压缩&#xff0c;我们还需要将该格式的数据转转想要的…

YUV图像格式详解

一、YUV格式 YUV格式有两大类&#xff1a;packed(打包)格式和planar(平面)格式。 packed&#xff1a;通常是几个相邻的像素组成一个宏像素&#xff08;macro-pixel&#xff09;&#xff0c;每个像素点的Y、U、V是连续交*存储的。 planar&#xff1a;使用三个数组分开存放Y、…

【图像格式】关于YUV格式的一些总结

关于YUV格式的一些总结 一、YUV和YCbCr 1、定义2、区别和联系 二、不同的采样格式 1、YUV4442、YUV4403、YUV4224、YUV4205、YUV4116、YUV410 三、YUV数据排列格式 1、四种数据排列方式 ①Planar Format②Semi-Planar Format③Tiled Semi-Planar Format④Interleaved Format 2…

YUV数据格式

与 RGB 编码方法类似&#xff0c;YUV 也是一种颜色编码方法。其中“Y”表示明亮度(Luminance 或 Luma)&#xff0c;也就是灰阶值&#xff0c;U 和 V 表示的则是色度(Chrominance 或 Chroma)&#xff0c;分别用 CrCb来表示&#xff0c;作用是描述影像色彩及饱和度&#xff0c;用…