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的更多相关文章

  1. linux高级应用第九章-正则表达式

    笔记部分 基础正则表达式: ^   第1个符号 ,以什么什么开头   ^m $  第2个符号,以什么什么结尾  m$    ,还表示空行,或空格,可以用cat  -An 试一下 ^$ 第3个符号,空行 ...

  2. javascript高级程序设计第二章知识点提炼

    这是我整理的javascript高级程序设计第二章的脑图,内容也是非常浅显与简单.希望您看了我的博客能够给我一些意见或者建议.

  3. 鸟哥的linux私房菜——第九章学习(vim编辑器)

    第九章vim编辑器 1.0).vi与vim Linux下文本界面的文书编辑器通常会有常常听到的就有: emacs, pico, nano, joe, 与 vim 等等. vi的优势: 所有的 Unix ...

  4. 鸟哥的Linux私房菜——第九章

    视频链接,推荐看B站 土豆网:http://www.tudou.com/programs/view/XmMDbjJHJC8 B站:http://www.bilibili.com/video/av966 ...

  5. 【linux高级程序设计】(第九章)进程间通信-管道 3

    有名管道 无名管道和有名管道: 1. 管道是特殊类型的文件,在满足先入先出的原则写可以读写,不能定位读写位置. 2.管道是单向的. 3.无名管道阻塞于读写位置,而有名管道阻塞在创建位置. 4.无名管道 ...

  6. 【linux高级程序设计】(第九章)进程间通信-管道 2

    文件描述符重定向 cat<test01  :将输入重定向到test01文件 cat>test02<test01  :将标准正确输出重定向到test02文件,输入设备重定向到test0 ...

  7. 【linux高级程序设计】(第十一章)System V进程间通信 4

    共享内存 共享内存主要用于实现进程间大量数据传输. 共享内存的数据结构定义: 系统对共享内存的限制: 共享内存与管道的对比: 可以看到,共享内存的优势: 1.共享内存只需复制2次,而管道需要4次 2. ...

  8. 【linux高级程序设计】(第十一章)System V进程间通信 2

    消息队列 消息队列是消息的链式队列,模型如下: 包括两种数据结构: msqid_ds消息队列数据结构 msg消息队列数据结构 struct msg_msg{ struct list_head m_li ...

  9. 【linux高级程序设计】(第十一章)System V进程间通信 1

    System V, 曾经也被称为 AT&T System V,是Unix操作系统众多版本中的一支. 传统上,System V 被看作是两种UNIX"风味"之一(另一个是 B ...

随机推荐

  1. spring里面的context:component-scan

    原文:http://jinnianshilongnian.iteye.com/blog/1762632 component-scan的作用的自动扫描,把扫描到加了注解Java文件都注册成bean &l ...

  2. wireshark 安装

    #yum install wireshark 安装完毕后 whereis wireshark 找不到可执行程序 /bin /sbin /usr/bin /usr/sbin下均没有. 实际上wiresh ...

  3. 使用Matrix-tree与它的行列式来解决生成树计数问题

    我又把Matrix写错啦 这东西讲课的时候竟然一笔带过了,淦 好吧这东西我不会证 那我们来愉快的看结论吧 啦啦啦 预备工作 你有一个 $ n $ 个点的图 比如说 5 /|\ / | \ 2--1-- ...

  4. js模板引擎之 Handlebars 基本用法

    模板引擎比较久远的一个技术,常见的模板引擎有 baiduTemplate(百度)\artTemplate(腾讯)\juicer(淘宝)\doT\ tmpl\ handlebars\ easyTempl ...

  5. Pascal小游戏 随机函数

    一个被人写滥了的小程序,新手学习,Pascal By Chaobs 初学者可以用它来学习随机函数的运用,当然你完全可以自己写一个随机函数. var   player1,player2:longint; ...

  6. Python第三方模块tesserocr安装

    介绍 在爬虫过程中,难免会遇到各种各样的验证码,而大多数验证码还是图形验证码,这时候我们可以直接用 OCR 来识别. tesserocr 是 Python 的一个 OCR 识别库 ,但其实是对 tes ...

  7. django文件上传、图片验证码、抽屉数据库设计

    1.Django文件上传之Form方式 settings.py, ALLOWED_HOSTS = ['*'] INSTALLED_APPS = [ 'django.contrib.admin', 'd ...

  8. SELECTORS模块实现并发简单版FTP

    环境:windows, python 3.5功能:使用SELECTORS模块实现并发简单版FTP允许多用户并发上传下载文件 结构:ftp_client ---| bin ---| start_clie ...

  9. NOIP2018 集训(三)

    A题 Tree 问题描述 给定一颗 \(n\) 个点的树,树边带权,试求一个排列 \(P\) ,使下式的值最大 \[\sum_{i=1}^{n-1} maxflow(P_i, P_{i+1}) \] ...

  10. NOIP2018 集训(一)

    A题 Simple 时间限制:1000ms | 空间限制:256MB 问题描述 对于给定正整数\(n,m\),我们称正整数\(c\)为好的,当且仅当存在非负整数\(x,y\)使得\(n×x+m×y=c ...