无名管道:

1)只能用于具有亲缘关系的进程之间的通信(无名管道是某一个进程创建的,不像普通文件有路径,在文件系统中是不可见的,其他进程要想打开,只能通过继承的方式去打开)

2)半双工的通信模式,具有固定的读端和写端

3)管道可以看成是一种特殊的文件,对于它的读写可以使用文件IO如read、write函数。

4)管道是基于文件描述符的通信方式。当一个管道建立时,它会创建两个文件描述符fd[0]和fd[1]。其中fd[0]固定用于读管道,而fd[1]固定用于写管道。

注意事项:
1)当管道中无数据时,读操作会阻塞

2)管道中有数据,将写端关闭,可以将数据读出

3)管道中无数据,将写端关闭,读操作会立即返回

4)管道中装满数据写阻塞,一旦有4k空间,写继续

5)只有在管道的读端存在时,向管道中写入数据才有意义。否则,会导致管道破裂,向管道中写入数据的进程将收到内核传来的SIGPIPE信号(通常Broken        pipe错误)。

6)不管pipe还是FIFO当把读端和写端都关闭的时候,管道存放在内存中的内容都会被自动释放

7)当用open打开的时候,当只打开读端,或者只打开写端,open会阻塞

创建无名管道:

int pipe(int pipefd[2]);

参数:文件描述符 fd[0]:读端 fd[1]:写端

成功返回 0 ,失败返回 -1

 例子1:管道中没有数据时读操作阻塞

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
int fd[];
char buf[] = {};//缓存 if(pipe(fd)!=)// 创建无名管道
{
perror("pipe fail: ");
exit();
}
printf("%d %d\n",fd[],fd[]);//打开的文件描述符,此处为3,4 默认打开 0,1,2,标准输入,输出,出错
//管道中没有数据的时候读阻塞
// write(fd[],"hello",); //此处不向管道写数据时,读操作会阻塞,管道中有数据时,读操作后结束进程
read(fd[],buf,);
printf("%s",buf);
putchar(); // '\n'
return ;
}

测试:读操作一直阻塞

 例子2:管道中有数据,将写端关闭,可以将数据读出

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
int fd[];
char buf[] = {};//缓存
if(pipe(fd)!=)// 创建无名管道
{
perror("pipe fail: ");
exit();
}
printf("%d %d\n",fd[],fd[]);//打开的文件描述符,默认打开 0,1,2
//管道中有数据,写端关闭,可以将数据读出
write(fd[],"",); //向管道中写入数据,然后关闭写端
close(fd[]);
read(fd[],buf,);
printf("%s",buf);
putchar(); // '\n'
return ;
}

测试:

例子3:管道中无数据,将写端关闭,读操作会立即返回

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
int fd[];
char buf[] = {};//缓存
if(pipe(fd)!=)// 创建无名管道
{
perror("pipe fail: ");
exit();
}
printf("%d %d\n",fd[],fd[]);//打开的文件描述符,默认打开 0,1,2
//写端关闭,管道中无数据,读操作立即返回
close(fd[]);
read(fd[],buf,); return ;
}

测试:管道中无数据,写端关闭,读操作直接返回

 例子4:管道大小 64K

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int main(int argc, const char *argv[])
{
int fd[];
char buf[] = {};//缓存
if(pipe(fd)!=)// 创建无名管道
{
perror("pipe fail: ");
exit();
}
printf("%d %d\n",fd[],fd[]);//打开的文件描述符,默认打开 0,1,2
//管道大小 64k
int num = ;
ssize_t size;
while() //循环一直运行,当写入 64K 后悔阻塞
{
size = write(fd[],"",);
printf("size = %ld\n",size); //每次写入1024个字节,即 1K ,此次编译会警告
num++;
printf("num = %d\n",num);
}
return ;
}

测试:

警告类型不匹配

 例子5: 管道中装满数据写阻塞,一旦有4k空间,写继续

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> //int pipe(int pipefd[2]); int main(int argc, const char *argv[])
{
int fd[]; char buf_w[] = {}; //一次写入 64K 数据
char buf_r[] = {}; //一次读出 4K 数据 if(pipe(fd)!=)// 创建无名管道
{
perror("pipe fail: ");
exit();
} printf("%d %d\n",fd[],fd[]);//打开的文件描述符,默认打开 0,1,2 //管道中装满数据写阻塞,一旦有 4k, 才可以继续进行写操作
write(fd[],buf_w,);//一次写入 64k
// read(fd[0],buf_r,4096); //一次读出4k,在进行写操作 ,程序直接结束
read(fd[],buf_r,); //一次读出 4k-1,在进行写操作 ,此时运行程序阻塞
write(fd[],"a",); // 先读出 4K 数据在写一个字符,或者读4K - 1 个字符,在进行写操作 return ;
}

测试:当读出 4K 数据时可以正常写入,当读出 4K-1 数据时 程序阻塞

Linux 进程间通信 无名管道(pipe)的更多相关文章

  1. Linux 进程间通信之管道(pipe),(fifo)

     无名管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信: 定义函数: int pipe(int f ...

  2. linux进程间通信--无名管道

    管道 只能用于具有亲缘关系的进程之间通信是一个半双工的通信模式, 具有固定的写读端和写端,管道可以看成一种特殊的文件,对它可以使用普通的read.write等操作 管道的创建: #include &l ...

  3. Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)

    整理自网络 Unix IPC包括:管道(pipe).命名管道(FIFO)与信号(Signal) 管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道 ...

  4. Linux简单程序实例(GNU工具链,进程,线程,无名管道pipe,基于fd的文件操作,信号,scoket)

    一, GNU工具链简介: (1)编译代码步骤: 预处理 -> 编译 -> 汇编 -> 链接: 预处理:去掉注释,进行宏替换,头文件包含等工作: gcc -E test.c -o te ...

  5. 练习--LINUX进程间通信之无名管道PIPE

    IBM上放的这个系统不错,刚好可以系统回温一下LINUX的系统知识. http://www.ibm.com/developerworks/cn/linux/l-ipc/part1/ 感觉年纪大了,前几 ...

  6. Linux进程间通信之管道

    1,进程间通信 (IPC ) Inter-Process Communication 比较好理解概念的就是进程间通信就是在不同进程之间传播或交换信息. 2,linux下IPC机制的分类:管道.信号.共 ...

  7. Linux 进程间通信(二) 管道

    Linux 进程间通信-管道 进程是一个独立的资源分配单位,不同进程之间的资源是相互独立的,没有关联,不能在一个进程中直接访问另一个进程中的资源.但是,进程不是孤立的,不同的进程之间需要信息的交换以及 ...

  8. Linux -- 进程间通信之管道

    管道是 Linux 里的一种文件类型,同时也是 Linux 系统下进程间通信的一种方式   创建一个管道文件有两种方式:  Shell 下命令 mkfifo + filename,即创建一个有名管道 ...

  9. linux之无名管道

    1.查看命令: man 2 pipe 2.头文件:#include <unistd.h> 3.函数原型: int pipe(int pipefd[2]); a.pipefd[2] :无名管 ...

随机推荐

  1. python面试题之如何用Python找出你目前在哪个目录?

    >>> import os >>> os.getcwd() 'C:\Users\lifei\AppData\Local\Programs\Python\Python ...

  2. 修改elementUI 分页器背景色

    添加background .sysBox .el-pagination.is-background .el-pager li:not(.disabled).active { background-co ...

  3. Spring项目下js文件无法引用

    问题:最近练习spring-mvc框架的时候,引用了jQuery,但是运行的时候,jQuery做的事情都没有响应,代码也没有任何报错,在网上找了一下,发现是由于spring配制的是/,所有的资源都被屏 ...

  4. 【专业的 Markdown 编辑写作软件】MWeb for Mac基本使用教程

    MWeb for Mac是一款专业的 Markdown 编辑写作软件,可以生成MarkDown编辑器和静态博客,在记日记的时候,你可以使用插入图片的功能,使用MWeb软件你可以拖拽或直接粘贴即可插入图 ...

  5. react-router v3和v4区别

    1.默认路由 v3 <IndexRoute> v4 <Route exact> 2.授权路由 import Redirect from 'react-router-dom' & ...

  6. JMeter Http请求之content-type用法

    转载自https://www.cnblogs.com/imyalost/p/6726795.html 本文讲三种content-type以及在Jmeter中对应的参数输入方式 第一部分:目前工作中涉及 ...

  7. Vue学习笔记【7】——Vue指令之v-model和双向数据绑定

    v-model是唯一可以实现双向数据绑定的vue指令 单向数据绑定:修改内存中的数据,页面上同步更改.v-bind <!-- v-bind 只能实现数据的单向绑定,从 M 自动绑定到 V, 无法 ...

  8. 线段树双tag+差分数组——cf1208E

    写了一上午 /* 对于每个数组a[],先排序然后从大到小把a[i]放进线段树更新 设a[i]的位置是pos,那么其可更新的区间是[pos,w-(li-pos)] 线段树结点保存 tag=now表示当前 ...

  9. 基础课(一)Cisco Packet Tracer Student模拟器简单的运用

    一.相同设备之间用交叉线,不同设备之间用直通线 如上图中的简单的两个PC机相连,交叉线相连的两个PC机是能ping同,直通线相连的两台PC机不通,ipconfig可以查看本机设备的网络配置 time= ...

  10. BZOJ 3252: 攻略(思路题)

    传送门 解题思路 比较好想的一道思路题,结果有个地方没开\(long\) \(long\) \(wa\)了三次..其实就是模仿一下树链剖分,重新定义重儿子,一个点的重儿子为所有儿子中到叶节点权值最大的 ...