【linux高级程序设计】(第九章)进程间通信-管道 1
Linux操作系统所支持的主要进程间的通信机制。

无名管道 PIPE
cat test.txt| grep hello
上面这种管道,将一个命令的输出作为另一个命令的输入,而这种管道是临时的,命令执行完成后将自动消失,称为无名管道。
int pipe (int __pipedes[2]) :创建无名管道
如果执行成功,pipe将存储两个整型文件描述符于__pipedes[0](只能读)和__pipedes[1](只能写)中,它们分别指向管道的两端。如果需要双工的,需要建立两个管道。

读写无名管道
必须确认还存在一个进程,可以使进程自己。默认以阻塞方式读写管道,如果修改可以使用fcntl函数实现。
(1)以阻塞方式读取无名管道,且当前没有进程可以访问写端
- 如果管道现有数据无数据,立即返回0
- 如果管道现有数据大于要读出的数据,立即读取期望大小的数据
- 如果管道现有数据小于要读出的数据,立即读取所有数据
第一种情况
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h> int main(void)
{
int p[];
pipe(p);
close(p[]); //断开当前进程与管道写端的联系
char buf[];
memset(buf, '\0', );
int ret = -;
ret = read(p[], buf, ); //阻塞读,无数据,无进程关联写,立即返回
printf("buf = %s\n", buf);
}

第二、三种情况
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h> int main(void)
{
int p[];
pipe(p);
write(p[], "helloworld", ); //写入10个字节
close(p[]); //断开当前进程与管道写端的联系
char buf[];
memset(buf, '\0', );
int ret = -;
ret = read(p[], buf, ); //有数据,且大于期望读出值
printf("first, ret = %d, buf = %s\n", ret, buf);
ret = read(p[], buf, ); //有数据,且小于期望读出值
printf("second, ret = %d, buf = %s\n", ret, buf);
}

(2)以阻塞方式读取无名管道,且当前有进程可以访问写端
- 管道中无任何数据,读操作阻塞
- 管道中有数据,现有数据大小小于期望读出值,读出现有数据并返回。
- 管道中有数据,现有数据大小大于期望读出值,读出期望大小的数据并返回。
第一种情况
int main(void)
{
int p[];
pipe(p);
char buf[];
memset(buf, '\0', );
int ret = -;
ret = read(p[], buf, ); //阻塞读,无数据,无进程关联写,立即返回
printf("buf = %s\n", buf);
}
阻塞了,通过Ctrl+C退出。

第二、三种情况(其实跟之前的代码比就少了一句close)
int main(void)
{
int p[];
pipe(p);
write(p[], "helloworld", ); //写入10个字节
char buf[];
memset(buf, '\0', );
int ret = -;
ret = read(p[], buf, ); //有数据,且大于期望读出值
printf("first, ret = %d, buf = %s\n", ret, buf);
ret = read(p[], buf, ); //有数据,且小于期望读出值
printf("second, ret = %d, buf = %s\n", ret, buf);
}

(3)如果以阻塞方式写无名管道,如果当前没有可以访问读端的进程,写操作将收到SIGPIPE信号,write返回-1.
#include<stdio.h>
#include<string.h>
#include<signal.h> void handler(int sig)
{
if(SIGPIPE == sig)
printf("recv SIGPIPE\n");
}
int main(void)
{
int p[];
signal(SIGPIPE, handler);
pipe(p);
close(p[]); //断开当前进程与管道读端的联系
int ret = -;
ret = write(p[], "helloworld", ); //写入10个字节
printf("ret = %d\n", ret);
}

(4)如果以阻塞方式写无名管道,如果当前管道已经满,则阻塞当前进程。多个进程试图写管道需要避免竞争的机制。写入建议小于PIPE_BUF(默认4096)大小。
(5)如果以O_NDELAY或O_NONBLOCK设置了管道的读端,如果管道中没有数据,将立即返回-1,且置errno为EAGAIN错误
(6)如果以O_NDELAY或O_NONBLOCK设置了管道的写端,如果管道中没有足够空间,将立即返回-1,且置errno为EAGAIN错误
【linux高级程序设计】(第九章)进程间通信-管道 1的更多相关文章
- linux高级应用第九章-正则表达式
笔记部分 基础正则表达式: ^ 第1个符号 ,以什么什么开头 ^m $ 第2个符号,以什么什么结尾 m$ ,还表示空行,或空格,可以用cat -An 试一下 ^$ 第3个符号,空行 ...
- javascript高级程序设计第二章知识点提炼
这是我整理的javascript高级程序设计第二章的脑图,内容也是非常浅显与简单.希望您看了我的博客能够给我一些意见或者建议.
- 鸟哥的linux私房菜——第九章学习(vim编辑器)
第九章vim编辑器 1.0).vi与vim Linux下文本界面的文书编辑器通常会有常常听到的就有: emacs, pico, nano, joe, 与 vim 等等. vi的优势: 所有的 Unix ...
- 鸟哥的Linux私房菜——第九章
视频链接,推荐看B站 土豆网:http://www.tudou.com/programs/view/XmMDbjJHJC8 B站:http://www.bilibili.com/video/av966 ...
- 【linux高级程序设计】(第九章)进程间通信-管道 3
有名管道 无名管道和有名管道: 1. 管道是特殊类型的文件,在满足先入先出的原则写可以读写,不能定位读写位置. 2.管道是单向的. 3.无名管道阻塞于读写位置,而有名管道阻塞在创建位置. 4.无名管道 ...
- 【linux高级程序设计】(第九章)进程间通信-管道 2
文件描述符重定向 cat<test01 :将输入重定向到test01文件 cat>test02<test01 :将标准正确输出重定向到test02文件,输入设备重定向到test0 ...
- 【linux高级程序设计】(第十一章)System V进程间通信 4
共享内存 共享内存主要用于实现进程间大量数据传输. 共享内存的数据结构定义: 系统对共享内存的限制: 共享内存与管道的对比: 可以看到,共享内存的优势: 1.共享内存只需复制2次,而管道需要4次 2. ...
- 【linux高级程序设计】(第十一章)System V进程间通信 2
消息队列 消息队列是消息的链式队列,模型如下: 包括两种数据结构: msqid_ds消息队列数据结构 msg消息队列数据结构 struct msg_msg{ struct list_head m_li ...
- 【linux高级程序设计】(第十一章)System V进程间通信 1
System V, 曾经也被称为 AT&T System V,是Unix操作系统众多版本中的一支. 传统上,System V 被看作是两种UNIX"风味"之一(另一个是 B ...
随机推荐
- 《Cracking the Coding Interview》——第13章:C和C++——题目9
2014-04-25 20:37 题目:请设计一个字节对齐的malloc函数,配套上对应的free函数.要求这个函数分配出的内存块儿的首地址是某个值n的整数倍,n是2的整次幂,比如128.1024之类 ...
- USACO Section1.5 Number Triangles 解题报告
numtri解题报告 —— icedream61 博客园(转载请注明出处)--------------------------------------------------------------- ...
- C++的字符输入
字符串的输入有6中方式,这六种方式各有各的特点,我这篇学习笔记是自己的经验总结,没有去探讨内存,函数库等的复杂问题,仅仅是为了实用: 第一:cin cin一次接受一个字符,所以有的人会选择定义一个字符 ...
- Python 3基础教程5-while循环语句
本文开始介绍循环语句,和其他编程语言一样,Python中有while循环和for循环,这里介绍while循环. 语法: while 条件表达式为真: 做一些事情 实际生活中有很多这样的循环场景,这里举 ...
- Rbac_权限管理
click!!! https://github.com/ugfly1210/rbac_100 有关于 rbac 的所有代码,包括 README. 用户和角色 : 多对多字段放在哪张表更好点? 用户找角 ...
- iOS 实现设备应用之间的相互切换
今天突发奇想,想做个应用之间能够切换的demo. 前提条件是,你得知道对应应用程序的URL Scheme.URL Scheme不一定和bundle id相同,但是,一定要是一致的. [[UIAppli ...
- Android 开发中Service完全解析
定义:服务,是Android四大组件之一,属于计算型组件 作用:提供 需在后台长期运行的服务 生命周期: 在Service的生命周期里,常用的有: (1) 4个手动调用的方法 手动调 ...
- 【bzoj4974】字符串大师 逆模拟KMP
题目描述 一个串T是S的循环节,当且仅当存在正整数k,使得S是$T^k$(即T重复k次)的前缀,比如abcd是abcdabcdab的循环节.给定一个长度为n的仅由小写字符构成的字符串S,请对于每个k( ...
- CentOS 7添加本地回环地址
CentOS 7添加本地回环地址 1. 临时添加ip addr add 10.10.1.1/32 dev lo:1重启失效2.永久添加cd /etc/sysconfig/network-scripts ...
- [THUWC2017][bzoj5020] 在美妙的数学王国中畅游 [LCT+泰勒展开]
题面 LOJ传送门 思路 这里很重要 它提示我们,把给定的三个函数泰勒展开,并用LCT维护每一项泰勒展开式的值,维护十几项就满足了题目的精度要求 我们考虑一个函数在0位置的泰勒展开 $f(x)=\su ...