搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
笔触狂放9
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
应用 OpenCV 进行 增强相关系数(ECC)最大化的图像配准_findtransformecc
2
因果推断与机器学习中的推荐系统与个性化_因果推荐系统
3
《C++ AMP:用Visual C++加速大规模并行计算》——1.2 CPU并行技术
4
3.1_3 连续分配管理方式
5
Mac os 本地化localizations_mac如何配置localization
6
002——编译鸿蒙(Liteos -a)
7
android手势检测类的扩展支持单点和多点触摸_android手势 单点隐藏控件
8
AndroidStudio实现用户登录注册界面代码(二)_andriod studio 登录系统 cadn
9
【力扣】322-零钱兑换_零钱兑换力扣
10
RNNoise: 一种致力于实时全频段语音增强的DSP+深度学习混合方法
当前位置:
article
> 正文
Linux文件类型之 管道_linux 管道文件
作者:笔触狂放9 | 2024-03-08 20:33:09
赞
踩
linux 管道文件
管道是Linux中很重要的一种
通信方式
,是把一个程序的输出直接连接到另一个程序的输入,
常说的管道多是指无名管道
,
无名管道只能用于具有亲缘关系的进程之间,
这是它与有名管道的最大区别。
有名管道叫named pipe或者FIFO(先进先出),可以用函数mkfifo()创建。
Linux管道的实现机制
从本质上说,管道也是一种文件,但它又和一般的文件有所不同,管道可以克服使用文件进行通信的两个问题,具体表现为:
· 限制管道的大小。实际上,管道是一个固定大小的缓冲区。在Linux中,该缓冲区的大小为1页,即4K字节,使得它的大小不象文件那样不加检验地增长。使用单个固定缓冲区也会带来问题,比如在写管道时可能变满,当这种情况发生时,随后对管道的write()调用将默认地被阻塞,等待某些数据被读取,以便腾出足够的空间供write()调用写。
· 读取进程也可能工作得比写进程快。当所有当前进程数据已被读取时,管道变空。当这种情况发生时,一个随后的read()调用将默认地被阻塞,等待某些数据被写入,这解决了read()调用返回文件结束的问题。
注意:
从管道读数据是
一次性
操作,数据一旦被读,它就从管道中被抛弃,释放空间以便写更多的数据。
1. 管道的结构
在 Linux 中,管道的实现并没有使用专门的数据结构,而是借助了文件系统的file结构和VFS的索引节点inode。通过将两个 file 结构指向同一个临时的 VFS 索引节点,而这个 VFS 索引节点又指向一个物理页面而实现的。
2.管道的读写
管道实现的源代码在
fs/pipe.c
中,在pipe.c中有很多函数,其中有两个函数比较重要,即管道读函数pipe_read()和管道写函数pipe_wrtie()。管道写函数通过将字节复制到 VFS 索引节点指向的物理内存而写入数据,而管道读函数则通过复制物理内存中的字节而读出数据。当然,内核必须利用一定的机制同步对管道的访问,为此,内核使用了锁、等待队列和信号。
当写进程向管道中写入时,它利用标准的库函数write(),系统根据库函数传递的文件描述符,可找到该文件的 file 结构。file 结构中指定了用来进行写操作的函数(即写入函数)地址,于是,内核调用该函数完成写操作。写入函数在向内存中写入数据之前,必须首先检查 VFS 索引节点中的信息,同时满足如下条件时,才能进行实际的内存复制工作:
·内存中有足够的空间可容纳所有要写入的数据;
·内存没有被读程序锁定。
如果同时满足上述条件,写入函数首先锁定内存,然后从写进程的地址空间中复制数据到内存。否则,写入进程就休眠在 VFS 索引节点的等待队列中,接下来,内核将调用调度程序,而调度程序会选择其他进程运行。写入进程实际处于可中断的等待状态,当内存中有足够的空间可以容纳写入数据,或内存被解锁时,读取进程会唤醒写入进程,这时,写入进程将接收到信号。当数据写入内存之后,内存被解锁,而所有休眠在索引节点的读取进程会被唤醒。
管道的读取过程和写入过程类似。但是,进程可以在没有数据或内存被锁定时立即返回错误信息,而不是阻塞该进程,这依赖于文件或管道的打开模式。反之,进程可以休眠在索引节点的等待队列中等待写入进程写入数据。当所有的进程完成了管道操作之后,管道的索引节点被丢弃,而共享数据页也被释放。
因为管道的实现涉及很多文件的操作,因此,当读者学完有关文件系统的内容后来读pipe.c中的代码,你会觉得并不难理解。
Linux 管道的创建和使用都要简单一些,唯一的原因是它需要更少的参数。实现与 Windows 相同的管道创建目标,Linux 和 UNIX 使用下面的代码片段:
pipe函数来创建 Linux 命名管道
int fd1[2];
if(pipe(fd1))
{ printf("pipe() FAILED: errno=%d",errno);
return 1;
}
Linux 管道对阻塞之前一次写操作的大小有限制。专门为每个管道所使用的内核级缓冲区确切为 4096 字节。 除非阅读器清空管道,否则一次超过 4K 的写操作将被阻塞。实际上这算不上什么限制,因为读和写操作是在不同的线程中实现的。
Linux 还支持命名管道。对这些数字的早期评论员建议我,为公平起见,应该比较 Linux 的命名管道和 Windows 的命名管道。我写了另一个在 Linux 上使用命名管道的程序。我发现对于 Linux 上命名的和未命名的管道,结果是没有区别。
Linux 管道比 Windows 2000 命名管道快很多,而 Windows 2000 命名管道比 Windows XP 命名管道快得多。
例子:
#include<stdio.h>
#include<unistd.h>
int main()
{
int n,fd[2]; // 这里的fd是文件描述符的数组,用于创建管道做准备的
pid_t pid;
char line[100];
if(pipe(fd)<0) // 创建管道
printf("pipe create error\n");
if((pid=fork())<0) //利用fork()创建新进程
printf("fork error\n");
else if(pid>0){ //这里是父进程,先关闭管道的读出端,然后在管道的写端写入“hello world"
close(fd[0]);
write(fd[1],"hello word\n",11);
}
else{
close(fd[1]); //这里是子进程,先关闭管道的写入端,然后在管道的读出端读出数据
n= read(fd[0],line,100);
write(STDOUT_FILENO,line,n);
}
exit(0);
}
声明:
本文内容由网友自发贡献,转载请注明出处:
【wpsshop博客】
推荐阅读
article
linux
c
嵌入式
工程师
笔试题,
嵌入式
软件
工程师
/
linux
c
程序员 笔试题...
一、什么叫可重入?可重入函数主要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数...
赞
踩
article
linux
编译
mqtt
静态库,无法为
arm
-
none
-
linux
-
gnueabi
-g ++编译器找...
I have the
arm
-
none
-
linux
-
gnueabi
-g++ compiler in the below ...
赞
踩
article
linux
下解决
qt
项目
error
while
loading
shared
libraries: ...
linux
下运行
qt
项目,能编译通过,但不能运行出应用程序_./
qt
-
unified
-
linux
-x64-4.6.1-o...
赞
踩
article
ubuntu
在线安装qt碰到的问题及解决_./qt-
unified
-
linux
-
x64
-4.6.1-...
ubuntu
中在线安装qt碰到的问题。_./qt-
unified
-
linux
-
x64
-4.6.1-
online
.
run
:...
赞
踩
article
Ubuntu安装QT:
error
whi
le
loading
shared
libraries: l...
【代码】Ubuntu安装QT:
error
whi
le
loading
shared
libraries:
libxcb
-...
赞
踩
article
解决
dbus
-
1
.
so.3
: no
version
information available 造成...
删除错误的lib
dbus
-
1
.
so.3
快捷方式,并将正确的lib
dbus
-
1
.
so.3
.XX.X拷贝到usr/lib64...
赞
踩
article
解决问题:
libbz2
.so.1: cannot open
shared
object
file
:...
解决缺少
libbz2
.so.1文件的问题。
err
or
while
loading
shared
libraries: l...
赞
踩
article
ubuntu
Linux
安装QT_qt-
unified
-
linux
-x64-4.6.1-
online
...
ubuntu
Linux
安装QT下载开源QT
Linux
安装包地址https://www.qt.io/download-o...
赞
踩
article
Linux
Qt6
安装
教程及错误解决_
ubuntu
安装
qt6
...
在
Linux
环境,通常为Ubuntu,
安装
Qt开发环境,
安装
教程以及遇到的错误解决_
ubuntu
安装
qt6
ubuntu
...
赞
踩
article
Ubuntu
安装Qt出现
bash
: ./
qt
-
unified
-
linux
-x64-
4.6
.1-onl...
Ubuntu
安装Qt出现
bash
: ./
qt
-
unified
-
linux
-x64-
4.6
.1-
online
.
run
: 权...
赞
踩
article
linux
ubuntu安装
qt
creater,配置
qt
环境到可运行
qt
项目_./
qt
-unifie...
一、安装
qt
creater1、搜索清华源,打开路径到
qt
位置,选择第二个文件,下载下来2、打开下载路径,执行chmod ...
赞
踩
article
linux
下
C++
#
include
的
搜索
路径
问题_
linux
include
搜索
路径
...
Linux c++_
linux
include
搜索
路径
linux
include
搜索
路径
...
赞
踩
article
linux
c
之g
c
c
编译出现error:
lvalue
required
as
unary
‘&‘ ...
1、问题 今天搞epoll实现io复用的时候g
c
c
编译出现这个错误
lvalue
required
as
unary
'&...
赞
踩
article
linux
使用
gcc
提示
后缀
无效
,
linux
– Gcc
编译
“无法计算对象文件的
后缀
:无法
编译
”.....
我实际上正在阅读LFS书(7.1版)
,
我在第53页被阻止.尝试
编译
gcc
,
我尝试了以下命令:./configure --...
赞
踩
article
arm
-
linux
-
gnueabihf
-gcc 5.2编译qt4.8.5_
dialogs
/qprin...
arm
-
linux
-
gnueabihf
-gcc 5.2编译qt4.8.5_
dialogs
/
qprintdialog
_un...
赞
踩
article
linux
signal
编译
不过,
Linux
编译
中
的各种
error
处理...
LDD3
中
的第一个例程就是scull,但是在新内核上
编译
的过程那叫一个坎坷。。。在此做出总结,希望可以帮到同路人。。。一...
赞
踩
article
【
FastDFS
】小伙伴们说按照我写的方式在
CentOS
8
服务器
上搭建
FastDFS
环境总报错?_...
这下在
CentOS
8
服务器
上
安装
FastDFS
不会报错了吧!_
c
entos
安装
fastdfs4.0
.6
c
ommon
...
赞
踩
article
Linux
学习
笔记(
12
)...
acpid 否 监听精灵进程 此进程监听并分配内核中的 acpi 事件adsl 否 内部 ADSL 开关控制 只...
赞
踩
article
Linux
:修改
文件
权限...
在
Linux
系统中,权限管理是
文件
和目录安全性的核心。
文件
权限是非常重要的,它们决定了哪些用户可以读取、写入或执行
文件
。...
赞
踩
article
linux
中文
语音
合成
软件,分享|
eSpeak
:
Linux
文本
转
语音
工具
...
eSpeak
是一款
Linux
命令行
工具
,能把
文本
转换成
语音
。它是一款简洁的
语音
合成
器,用C语言编写而成,它支持英语和...
赞
踩
相关标签
linux c嵌入式工程师笔试题
linux 编译mqtt静态库
linux
qt
ubuntu
运维
开发语言
qtcreator
qt5
installer
UOS
bash
权限