调用pipe函数时在内核中开辟一块缓冲区(称为管道)用于通信,它有一个读端一个写端,然后通过filedes参数传出给用户程序两个文件描述符,filedes[0]指向管道的读端,filedes[1]指向管道的写端(很好记就像0是标准输入1是标准输出一样)。所以管道在用户程序看起来就像一个打开的文通read(filedes[0]);或者write(filedes[1]);向这个文件读写数据其实是在读写内核缓冲区。 pipe函数调用成功返回0,调用失败返回-1。 开辟了管道之后如何实现两个进程间的通信呢?可以按下面的步骤通信。

1. 父进程调用pipe开辟管道,得到两个文件描述符指向管道的两端。
2. 父进程调用fork创建子进程,那么子进程也有两个文件描述符指向同一管道。

3. 父进程关闭管道读端,子进程关闭管道写端。父进程可以往管道里写,子进程可以从管道里读,管道是以环形队列实现的,数据从写端流入从读端流出,这样就实现了进程间通信。

代码如下:

#include<stdio.h>

#include<unistd.h>

#include<errno.h>

#include<string.h>

int main()

{

int pipe_fd[2];   //读、写

if(pipe(pipe_fd)<0)

{

printf("pipe error:%d",strerror(errno));

return 1;

}

pid_t id=fork();//创建管道

if(id==0)//child

{//write

close(pipe_fd[0]);   //关掉读端

char*str="hello bit\n";

int count=0;

while(1)

//while(count<5)

{

write(pipe_fd[1],str,strlen(str));

count++;

sleep(1);

//  printf("write success:%d\n",count++);

}

close(pipe_fd[1]);

sleep(20);

}

else

{//read

close(pipe_fd[1]);  //关掉写端

char buf[1024];

//while(1)

int count=0;

while(count++<5)

{

//sleep(5);

buf[0]='\0';

ssize_t sz=read(pipe_fd[0],buf,sizeof(buf)-1);

if(sz>0)

{

buf[sz]='\0';

printf("father msg from child:%s\n",buf);

}

}

close(pipe_fd[0]);

sleep(20);

int status=0;

pid_t ret=waitpid(id,&status,0);

if(ret==id)

{

printf("wait sucess,get sig:%d\n,exit code:%d\n",status & 0xff,(status>>8) & 0xff);  //低八位是退出信息,次低八位是退出码(进程的退出码范围是0-255)

}

}

}

1. 如果所有指向管道写端的文件描述符都关闭了(管道写端的引用计数等于0),但仍然有进程从管道的读端读数据,那么管道中剩余的数据都被读取后,再次read会返回0,就像读到文件末尾一样;

2. 如果有指向管道写端的文件描述符没关闭(管道写端的引用计数大于0),但持有管道写端的进程也没有向管道中写数据,这时有进程从管道读端读数据,那么管道中剩余的数据都被读取后,再次read会阻塞,直到管道中有数据可读了才读取数据并返回。

3. 如果所有指向管道读端的文件描述符都关闭了(管道读端的引用计数等于0),这时有进程向管道的写端write,那么该进程会收到信号SIGPIPE,通常会导致进程异常终止。

4. 如果有指向管道读端的文件描述符没关闭(管道读端的引用计数大于0),但持有管道读端的进程也没有从管道中读数据,这时有进程向管道写端写数据,那么在管道被写满时再 次write会阻塞,直到管道中有空位置了才写数据并返回。

有兴趣的童鞋可以验证一下!

转载于:https://blog.51cto.com/xiexiankun/1832674

linux中pipe相关推荐

  1. Linux中的pipe(管道)与named pipe(FIFO 命名管道)

    catalogue 1. pipe匿名管道 2. named pipe(FIFO)有名管道 1. pipe匿名管道 管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入 ...

  2. linux有名管道大小,Linux中的pipe与named pipe(FIFO),即管道和命名管道

    Linux 管道对阻塞之前一次写操作的大小有限制. 专门为每个管道所使用的内核级缓冲区确切为 4096 字节. 除非阅读器清空管道,否则一次超过 4K 的写操作将被阻塞. 实际上这算不上什么限制,因为 ...

  3. linux内核定义的常用信号6,Linux中的信号

    在 Linux 中,理解信号的概念是非常重要的.这是因为,信号被用于通过 Linux 命令行所做的一些常见活动中.例如,每当你按 Ctrl+C 组合键来从命令行终结一个命令的执行,你就使用了信号.每当 ...

  4. Linux中errno使用

    当linux中的C api函数发生异常时,一般会将errno变量(需include errno.h)赋一个整数值,不同的值表示不同的含义,可以通过查看该值推测出错的原因,在实际编程中用这一招解决了不少 ...

  5. 专业介绍Linux中的进程管理

    Linux中的进程管理 1.什么是进程? 1)进程就是系统中处于执行期的工作. 对于[执行]两个字需要作出特别解释:执行并不同于运行,因为系统中的进程的状态大概分为四种: 进程状态 R(Running ...

  6. Linux中命令链接操作符的十个最佳实例

    转载: http://www.linuxeden.com/html/softuse/20140112/147406.html http://www.tecmint.com/chaining-opera ...

  7. Linux中查看日志文件的正确姿势,求你别tail走天下了!

    作为一个后端开发工程师,在Linux中查看查看文件内容是基本操作了.尤其是通常要分析日志文件排查问题,那么我们应该如何正确打开日志文件呢?对于我这种小菜鸡来说,第一反应就是 cat,tail,vi(或 ...

  8. Linux中一切皆文件

    Linux中一切皆文件 1. Linux中所有内容都是以文件的形式保存和管理,即:一切皆文件. 普通文件是文件. 目录(在win下称为文件夹)是文件. 硬件设备(键盘.硬盘.打印机)是文件. 套接字( ...

  9. Linux 中的零拷贝技术,第 2 部分

    技术实现 本系列由两篇文章组成,介绍了当前用于 Linux 操作系统上的几种零拷贝技术,简单描述了各种零拷贝技术的实现,以及它们的特点和适用场景.第一部分主要介绍了一些零拷贝技术的相关背景知识,简要概 ...

最新文章

  1. UVa11770 - Lighting Away(排序+DFS)
  2. Java迭代器使用注意
  3. java开源框架有哪些_java web开发框架有哪些
  4. Python 各种运行错误(如:SyntaxError :invalid syntax)
  5. 互联网1分钟 |1218
  6. JS实现Unix时间戳(Unix timestamp)转换工具-toolfk程序员工具网
  7. Microsoft Teams的Outgoing Webhook开发入门
  8. Python中的getpass模块
  9. dll创建及调用(VS2005)
  10. 解题报告——-2018级2016第二学期第三周作业
  11. 八、异常、java笔记
  12. java并发包源码分析
  13. Python 宽学网
  14. 综合实践活动信息技术小学版第三册电子课本_摆事实,讲道理!电子商务讲师证报名入口和费用...
  15. 利用leafcutter做可变剪切(新手向)
  16. 我在低处仰望,梦过尘世幻想。
  17. 音频播放时小喇叭动画
  18. 力扣 (LeetCode)-对称二叉树,树|刷题打卡
  19. Ubuntu16(ROS_Kinetic)海康威视网络摄像机(单目)内参标定
  20. 零基础HTML教程(4)--动手创建第一个网页吧

热门文章

  1. 获取DataRow某列的值的封装
  2. 关闭Windows 2000/XP/2003默认共享
  3. 设置Squid Cache_mem大小
  4. Iframe 用法浅析
  5. junit集成Hamcrest测试集合中某个属性是否包含特定值
  6. 提高C++性能的编程技术笔记:内联+测试代码
  7. 一维码Codabar简介及其解码实现(zxing-cpp)
  8. C++11中shared_ptr的使用
  9. 【Qt】QDebug和log4cplus的联合使用
  10. linux终端vi退出命令,如何从命令行关闭vim?