文章目录

  • 基本概念
  • 父子进程共享管道
  • 参考文档
基本概念

    从概念上讲,管道是两个进程之间的连接,一个进程的标准输出成为另一个进程的标准输入。在UNIX操作系统中,管道用于进程间通信。

  • 管道只是单向通信,即我们可以这样使用管道:一个进程向管道写入数据,另一个进程从管道读取数据。管道,是内存中被视为“虚拟文件”的一块区域。
  • 管道可以被创建进程及其所有子进程读写。一个进程可以写入这个“虚拟文件”或管道,另一个相关进程可以从中读取。
  • 如果在某个内容写入管道之前,某个进程试图读取该内容,则该进程将挂起,直到内容被写入。
  • 管道系统调用在进程的打开文件表中找到前两个可用位置,并将其分配给管道的读取和写入端。

    C语言语法:

int pipe(int fds[2]);参数:
fd[0] 将是管道读取端的fd(文件描述符)
fd[1] 将是管道写入端的fd
返回值:0表示成功,-1表示失败。

    管道表现为FIFO(先进先出),管道实现类似队列数据结构。读写大小不是必须一致。在管道中,我们可以一次写入512字节,但可以一次只读取1字节。

// C program to illustrate
// pipe system call in C
#include <stdio.h>
#include <unistd.h>
#define MSGSIZE 16
char* msg1 = "hello, world #1";
char* msg2 = "hello, world #2";
char* msg3 = "hello, world #3"; int main()
{ char inbuf[MSGSIZE]; int p[2], i; if (pipe(p) < 0) exit(1); /* continued *//* write pipe */write(p[1], msg1, MSGSIZE); write(p[1], msg2, MSGSIZE); write(p[1], msg3, MSGSIZE); for (i = 0; i < 3; i++) { /* read pipe */read(p[0], inbuf, MSGSIZE); printf("% s\n", inbuf); } return 0;
}

    输出:

hello, world #1
hello, world #2
hello, world #3
父子进程共享管道

    当我们在任何进程中使用fork时,文件描述符在子进程和父进程之间保持打开状态。如果我们在创建管道后调用fork,则父级和子级可以通过管道进行通信。

// C program to illustrate
// pipe system call in C
// shared by Parent and Child
#include <stdio.h>
#include <unistd.h>
#define MSGSIZE 16
char* msg1 = "hello, world #1";
char* msg2 = "hello, world #2";
char* msg3 = "hello, world #3"; int main()
{ char inbuf[MSGSIZE]; int p[2], pid, nbytes; if (pipe(p) < 0) exit(1); /* continued */if ((pid = fork()) > 0) { write(p[1], msg1, MSGSIZE); write(p[1], msg2, MSGSIZE); write(p[1], msg3, MSGSIZE); // Adding this line will // not hang the program // close(p[1]); wait(NULL); } else { // Adding this line will // not hang the program // close(p[1]); while ((nbytes = read(p[0], inbuf, MSGSIZE)) > 0) printf("% s\n", inbuf); if (nbytes != 0) exit(2); printf("Finished reading\n"); } return 0;
}

    输出:

hello world, #1
hello world, #2
hello world, #3
(hangs)         //program does not terminate but hangs

    在此代码中,在完成读/写之后,父级和子级都阻塞而不是终止进程,这就是程序挂起的原因。

  • 如果管道为空,并且我们调用read系统调用,那么如果没有进程打开写入端,则管道上的读取将返回EOF(返回值0)。
  • 如果其他进程打开了管道进行写入,则read将阻塞,以等待新的数据,因此代码输出挂起,因为写入端的父进程和子进程没有关闭。
参考文档

[1]Kadam Patel.pipe() System call[EB/OL].https://www.geeksforgeeks.org/pipe-system-call/,2019-06-12.

了解C语言中的pipe()系统调用相关推荐

  1. linux strcpy 用法,由Linux中管道的buffer,浅谈C语言中char类型字符串拷贝使用strcpy()和=赋值符号的区别...

    今天在写父子进程用两个单向管道通信时,出现了错误: Segmentation fault (core dumped) 打开core文件发现: 附上源码: 1 #include 2 #include 3 ...

  2. c语言中const对于define优点,为什么大多数C开发人员使用define而不是const?

    这有一个非常可靠的原因:C中的const并不意味着一些常量. 这只是意味着一个variables是只读的. 在编译器需要一个常量的地方(例如非VLA数组的数组大小),使用constvariables( ...

  3. c语言 recv_sin,C++_C语言中经socket接收数据的相关函数详解,recv()函数: 头文件:#incl - phpStudy...

    C语言中经socket接收数据的相关函数详解 recv()函数:头文件: #include #include 定义函数: int recv(int s, void *buf, int len, uns ...

  4. 快速搞懂C语言中exit(0)与exit(1)有什么区别??

    C语言中exit(0)与exit(1)有什么区别?? exit(1)表示异常退出,在退出前可以给出一些提示信息,或在调试程序中察看出错原因. exit(0)表示正常退出. return是语言级别的,是 ...

  5. c语言中signal函数详细解释说明

    c语言中signal函数详细解释说明     对于 信号处理函数 位于 <signal.h> 中. void ( *signal( int sig, void (* handler)( i ...

  6. c语言中管道符作用,由Linux中管道的buffer,浅谈C语言中char类型字符串拷贝使用strcpy()和=赋值符号的区别...

    今天在写父子进程用两个单向管道通信时,出现了错误: Segmentation fault (core dumped) 打开core文件发现: 附上源码: 1 #include 2 #include 3 ...

  7. c语言自动生成系统时间函数,使用C语言中的time函数获取系统时间

    使用C语言中的time函数获取系统时间 可以通过time()函数来获得计算机系统当前的日历时间(Calendar Time),处理日期时间的函数都是以本函数的返回值为基础进行运算.其原型为: time ...

  8. C语言中exit(0)与exit(1)的区别

    C语言中_exit(),exit(0)与exit(1)有什么区别 今天天气有点冷,当我在写消息队列的程序的时候,遇到了结束进程的这个问题,突然脑海里有点混乱,我是用_exit(),还是用exit(1) ...

  9. C语言中exit(0) 、exit(1) 和return的区别

    C语言中的exit 文字描述 代码验证 return 表示返回 , 函数返回 exit 表示程序退出 exit(0) 表示正常退出,代码为1 exit(1) 表示异常退出,代码为1 文字描述 retu ...

最新文章

  1. okl4 linux,Native OKL4 Android Stack
  2. 【Groovy】闭包 Closure ( 闭包中调用 Groovy 脚本中的方法 | owner 与 delegate 区别 | 闭包中调用对象中的方法 )
  3. php读取数组修改内容,php 数组如何修改值
  4. centos7中每天定时备份mysql数据库
  5. 三元表达式,递归,匿名函数,内置函数
  6. mysql 执行计划详解,Mysql中的explain执行计划详解(1)
  7. 在位运算中_Java常见的运算符(下)
  8. 【SpringMVC】SpringMVC : 注解 @EnableWebMvc
  9. Core官方DI解析(3)-ServiceCallSite.md
  10. 软件工程2第一次作业
  11. 高通QCA9377 WiFi蓝牙模块芯片介绍
  12. 用Python爬中国银行指定日期九点三十分汇率
  13. linux系统怎么连接显示器,Linux下笔记本外接显示器 · Eulerlee
  14. python if多个条件并列_Python if有多个条件怎么办
  15. 新手应该如何学习SEO优化
  16. 电子不停车收费系统(ETC)专题(1)——系统概述
  17. Linux下C程序调用库函数实现重启
  18. 文档格式转换工具对比
  19. 一部手机失窃引发的惊心动魄的战争
  20. 杭州电子科技大学acm--2000

热门文章

  1. 华炎魔方平台基本分析
  2. java 日期处理类
  3. 神武手游宠物加点方法及属性参考
  4. Java-PTA 无聊的小明来数1
  5. 分享一个小玩意 真菌UNITE物种分类数据库
  6. SOCKS代理的工作原理
  7. 智能音箱音效哪个好_2018最火4款智能音箱横评:哪款性价比最高?
  8. 计算机网络性能常见参数,计算机网络参数及其对网络性能的影响
  9. TOOL 一个裴蜀定理解析器
  10. 可编程计算机边长计算器,可编程科学计算器(Scientific Calculator Plus)