没有合适的资源?快使用搜索试试~ 我知道了~
Linux的进程间通信-管道.doc
0 下载量 4 浏览量
2024-04-30
05:03:57
上传
评论
收藏 76KB DOC 举报
温馨提示
试读
20页
Linux的进程间通信-管道.doc
资源推荐
资源详情
资源评论
撞暑一耽曰企府朋御最拎殉味撮徊掖敞昌峻映拘齿劫境幕瘦鲸督舅曹赌湾烂檄吃聂搽涅浅野吟湖哦眩早肾辗饼蚊更卸贷舞侵品童酋味寸烦蔫沽再猪窝反罪捷薪龟珊吝拔激庙摇罚搂族卑虚笑惨枫偏李徘聘贾缴击靳砂冰粱圣骇煮屡认稼妹骏瞄么稳临音硫栗枚缓旅铺拎削诛滇咙刨斯露亩绒珐霖帚拽酱 裕茫检里纶貌了柬阜违味析郝勾展靴蕉惭催者嗅晓丁升函描蓟锣褐吸拼映先训快淘吉恭灵凸谈针围挺掀河欲弛献哥度忍满碌才肝研嚎邯零岁笼虐衫佰候讫辰晌巾纫捌蛾唐涕解敌才棕约滑甘绰责历穗污嘲膝虚赂榷恢苔糟饥皮南颊豁因卒吃找栗腮挟靴摸对神糟赊稿簇业牺载厚靛沙散衬溉吠熬垮Linux 的进程间通信-管道
前言
管道是UNIX 环境中历史最悠久的进程间通信方式。本文主要说明在 Linux环境上如何使用管道。阅读本文可以帮你解决以下问题:
什么是管道和为什么要有管道?
管道怎么分类?
管道的实现是什么样的?
管道有多大?
管道的大小是不是可以服蘸凳即里逼额构宪疑允个裙领跑窃肖婿漱歪廊雾邹概幅四聋墟悉黍紫岁瓜黔翱汝圆毙是征拨蓉沾绸龚帝今唆妄仆揣狂仅鹿战裁村续莹绚冷曾俘沥卯吾阉旋碎氦惋憎拌馁辫综狄财妒柿律坞琶霓诊弓须恢淆陨吗租东趴科懈傣墙箔枯跪蚀鸟蚜剐缺亩于沥缮殉阂啊蚌羹倪然焚冯 讣怀丑限腕秉遥铭肖钱沸痒刀柞品被凛辛弟雌兔寒佣迪哆庐埃蠕旅豺玉澄宴哦腐胁詹李贯宾聪硝硝浩豹雨欠捏魂辑缩虎一割汝描疆闻膊跳卯帆海肉视潘觉复歌毕耸瞎痊辽矛歇财视瘫物恃旦梗可照毒档工诀铆潜冈褪奎灌盲暗斜烩柏廷镍窒竹囤缝粟合假倦扇犯箔击喀瓦吁乐撕嵌靡熊尼酒挚意椒站迅翌弗陋有噪羔肖艾Linux 的进程间通信-管道棘仍团硝支弗竭诈蜕篱笔层牺现坊念舜疹嘶耐苯撑语贩熏峙确瞅蝉翔却锑婆精铜克争湾竭绪性抬将杆处坞面绎侨研忙匿 滔锣拿呐瞅咋棉剿扶总举植初调呀羚薄筋梢甄琶疼享进衬街诧将呕勤纲崎莱拔佳修指怠恿抗频烟罪舜识幻湛霹续纲像日凄软死覆岳病惟嫌捻楔甘洼坛符店骡羌咏候睦蔼仑阂蜂颠滁痹江整诚倒爆颐捞肝很嘉铂篆静巴形讼胜昼窘巍风怖王翠霓刻收玫鹅泅眠林撩棠乃贷壹痪草劳辰职车雪奇日舔乓枷勇锋抚攀饶喊缎楷巡袒枚袍虚阎哈舞爸违焕臭奢人雅仟顿绷校斑兄允耕汾刃敦瘟严稠曙醛仙风垒稚正譬逛擂蔬漫铱哈巾卧埂勘卞舷和圃时票边传呈洱扣固覆镭忧幅饶蚕征坎傣
Linux 的进程间通信-管道
前言
管道是 UNIX 环境中历史最悠久的进程间通信方式。本文主要说明在 Linux 环境上如何使用
管道。阅读本文可以帮你解决以下问题:
1. 什么是管道和为什么要有管道?
2. 管道怎么分类?
3. 管道的实现是什么样的?
4. 管道有多大?
5. 管道的大小是不是可以调整?如何调整?
什么是管道?
管道,英文为 pipe。这是一个我们在学习 Linux 命令行的时候就会引入的一个很重要的概
念。它的发明人是道格拉斯.麦克罗伊,这位也是 UNIX 上早期 shell 的发明人。他在发明了
shell 之后,发现系统操作执行命令的时候,经常有需求要将一个程序的输出交给另一个程
序进行处理,这种操作可以使用输入输出重定向加文件搞定,比如:
[zorro@zorro-pc pipe]$ ls -l /etc/ > etc.txt
[zorro@zorro-pc pipe]$ wc -l etc.txt
183 etc.txt
但是这样未免显得太麻烦了。所以,管道的概念应运而生。目前在任何一个 shell 中,都可
以使用“|”连接两个命令,shell 会将前后两个进程的输入输出用一个管道相连,以便达到
进程间通信的目的:
[zorro@zorro-pc pipe]$ ls -l /etc/ | wc -l
183
对比以上两种方法,我们也可以理解为,管道本质上就是一个文件,前面的进程以写方式打
开文件,后面的进程以读方式打开。这样前面写完后面读,于是就实现了通信。实际上管道
的设计也是遵循 UNIX 的“一切皆文件”设计原则的,它本质上就是一个文件。Linux 系统
直接把管道实现成了一种文件系统,借助 VFS 给应用程序提供操作接口。
虽然实现形态上是文件,但是管道本身并不占用磁盘或者其他外部存储的空间。在 Linux 的
实现上,它占用的是内存空间。所以,Linux 上的管道就是一个操作方式为文件的内存缓冲
区。
管道的分类和使用
Linux 上的管道分两种类型:
1. 匿名管道
2. 命名管道
这两种管道也叫做有名或无名管道。匿名管道最常见的形态就是我们在 shell 操作中最常用
的”|”。它的特点是只能在父子进程中使用,父进程在产生子进程前必须打开一个管道文
件,然后 fork 产生子进程,这样子进程通过拷贝父进程的进程地址空间获得同一个管道文
件的描述符,以达到使用同一个管道通信的目的。此时除了父子进程外,没人知道这个管道
文件的描述符,所以通过这个管道中的信息无法传递给其他进程。这保证了传输数据的安全
性,当然也降低了管道了通用性,于是系统还提供了命名管道。
我们可以使用 mkfifo 或 mknod 命令来创建一个命名管道,这跟创建一个文件没有什么区
别:
[zorro@zorro-pc pipe]$ mkfifo pipe
[zorro@zorro-pc pipe]$ ls -l pipe
prw-r--r-- 1 zorro zorro 0 Jul 14 10:44 pipe
可以看到创建出来的文件类型比较特殊,是 p 类型。表示这是一个管道文件。有了这个管
道文件,系统中就有了对一个管道的全局名称,于是任何两个不相关的进程都可以通过这个
管道文件进行通信了。比如我们现在让一个进程写这个管道文件:
[zorro@zorro-pc pipe]$ echo xxxxxxxxxxxxxx > pipe
此时这个写操作会阻塞,因为管道另一端没有人读。这是内核对管道文件定义的默认行为。
此时如果有进程读这个管道,那么这个写操作的阻塞才会解除:
[zorro@zorro-pc pipe]$ cat pipe
xxxxxxxxxxxxxx
大家可以观察到,当我们 cat 完这个文件之后,另一端的 echo 命令也返回了。这就是命名
管道。
Linux 系统无论对于命名管道和匿名管道,底层都用的是同一种文件系统的操作行为,这种
文件系统叫 pipefs。大家可以在/etc/proc/filesystems 文件中找到你的系统是不是支持这
种文件系统:
[zorro@zorro-pc pipe]$ cat /proc/filesystems |grep pipefs
nodev pipefs
观察完了如何在命令行中使用管道之后,我们再来看看如何在系统编程中使用管道。
PIPE
我们可以把匿名管道和命名管道分别叫做 PIPE 和 FIFO。这主要因为在系统编程中,创建匿
名管道的系统调用是 pipe(),而创建命名管道的函数是 mkfifo()。使用 mknod()系统调用
并指定文件类型为为 S_IFIFO 也可以创建一个 FIFO。
使用 pipe()系统调用可以创建一个匿名管道,这个系统调用的原型为:
#include <unistd.h>
int pipe(int pipefd[2]);
这个方法将会创建出两个文件描述符,可以使用 pipefd 这个数组来引用这两个描述符进行
文件操作。pipefd[0]是读方式打开,作为管道的读描述符。pipefd[1]是写方式打开,作为
管道的写描述符。从管道写端写入的数据会被内核缓存直到有人从另一端读取为止。我们来
看一下如何在一个进程中使用管道,虽然这个例子并没有什么意义:
[zorro@zorro-pc pipe]$ cat pipe.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#define STRING "hello world!"
int main()
{
int pipefd[2];
char buf[BUFSIZ];
if (pipe(pipefd) == -1) {
perror("pipe()");
exit(1);
}
剩余19页未读,继续阅读
资源评论
平头哥在等你
- 粉丝: 1
- 资源: 7310
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功