Linux进程间通信-管道深入理解(转)
原文地址:https://www.linuxidc.com/Linux/2018-04/151680.htm
Linux进程通信系列文章将详细介绍各种通信方式的机制和区别
1.进程间通信
每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,进程B再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。

2、进程间通信方式
一、进程间通信-管道 https://www.linuxidc.com/Linux/2018-04/151680.htm
二、进程间通信-命名管道 https://www.linuxidc.com/Linux/2018-04/151681.htm
三、进程间通信-消息队列 https://www.linuxidc.com/Linux/2018-04/151682.htm
四、进程间通信-共享内存 https://www.linuxidc.com/Linux/2018-04/151683.htm
3、进程间通信-管道(pipe)
3.1 管道是如何通信的
(1)父进程创建管道,得到两个⽂件描述符指向管道的两端
(2)父进程fork出子进程,⼦进程也有两个⽂件描述符指向同⼀管道。
(3)父进程关闭fd[0],子进程关闭fd[1],即⽗进程关闭管道读端,⼦进程关闭管道写端(因为管道只支持单向通信)。⽗进程可以往管道⾥写,⼦进程可以从管道⾥读,管道是⽤环形队列实现的,数据从写端流⼊从读端流出,这样就实现了进程间通信。

3.2 利用管道实现通信
#include "stdio.h"
#include "unistd.h"
#include "string.h"
int main(int argc, char* argv[])
{
int fd[2];
int ret = pipe(fd);
if (ret == -1)
{
perror("pipe error\n");
return 1;
}
pid_t pid = fork();
if (pid == 0) // child
{
close(fd[0]);
int i = 0;
char* msg = "i am child\n";
while (i < 5)
{
write(fd[1],msg,strlen(msg));
sleep(2);
i++;
}
}
else if(pid > 0)
{
close(fd[1]);
char buf[256] = {0};
int j = 0;
while (j < 5)
{
int n = read(fd[0],buf,256);
if (n>0)
{
buf[n] = '\0';
}
printf("%s",buf);
j++;
}
}
else
{
perror("fork error\n");
return 1;
}
return 0;
}
运行结果:

3.3 管道读取数据的四种的情况
(1)读端不读,写端一直写

(2)写端不写,读端一直读

(3)读端一直读,写端关闭

(4)写端一直写,读端关闭

#include "stdio.h"
#include "unistd.h"
#include "string.h"
#include "sys/wait.h"
#include "sys/types.h"
int main(int argc, char* argv[])
{
int fd[2];
int status = 0;
int ret = pipe(fd);
if (ret == -1)
{
perror("pipe error\n");
return 1;
}
pid_t pid = fork();
if (pid == 0) // child
{
close(fd[0]);
int i = 0;
char* msg = "i am child\n";
while (i < 10)
{
write(fd[1],msg,strlen(msg));
sleep(1);
i++;
}
}
else if(pid > 0)
{
close(fd[1]);
char buf[256] = {0};
int j = 0;
while (j < 5)
{
int n = read(fd[0],buf,256);
if (n>0)
{
buf[n] = '\0';
}
printf("%s",buf);
j++;
}
close(fd[0]);
ret = waitpid(pid,&status,0);
printf("exit single(%d),exit(%d)\n", status & 0xff, (status >> 8) & 0xff);
}
else
{
perror("fork error\n");
return 1;
}
return 0;
}
运行结果:

使用kill -l 查看13号信号,可以知道13号信号代表SIGPIPE。
4、管道的特点
(1)管道只允许具有血缘关系的进程间通信,如父子进程间的通信。
(2)管道只允许单向通信。
(3)管道内部保证同步机制,从而保证访问数据的一致性。
5、管道的容量
测试管道容量大小只需要将写端一直写,读端不读且不关闭fd[0],即可。
#include "stdio.h"
#include "unistd.h"
#include "string.h"
#include "sys/wait.h"
#include "sys/types.h"
int main(int argc, char* argv[])
{
int fd[2];
int status = 0;
int ret = pipe(fd);
if (ret == -1)
{
perror("pipe error\n");
return 1;
}
pid_t pid = fork();
if (pid == 0) // child
{
close(fd[0]);
int i = 1;
while (i)
{
write(fd[1],"A",1);
printf("pipe capacity: %d\n",i++);
}
close(fd[1]);
}
else if(pid > 0)
{
close(fd[1]);
waitpid(pid,NULL,0);
close(fd[0]);
}
else
{
perror("fork error\n");
return 1;
}
return 0;
}
运行结果:

由此可见,管道大小为64k
本文永久更新链接地址:https://www.linuxidc.com/Linux/2018-04/151680.htm
Linux进程间通信-管道深入理解(转)的更多相关文章
- Linux进程间通信—管道
Linux下的进程通信手段基本上是从UNIX平台上的进程通信手段继承而来的.而对UNIX发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间 ...
- Linux进程间通信:管道,信号量,消息队列,信号,共享内存,套接字
Linux下的进程通信手段基本上是从UNIX平台上的进程通信手段继承而来的.而对UNIX发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间 ...
- Linux进程间通信 -- 管道(pipe)
前言 进程是一个独立的资源管理单元,不同进程间的资源是独立的,不能在一个进程中访问另一个进程的用户空间和内存空间.但是,进程不是孤立的,不同进程之间需要信息的交互和状态的传递,因此需要进程间数据 ...
- Linux进程间通信---管道和有名管道
一.管道 管道:管道是一种半双工的通信方式,数据只能单方向流动,而且只能在具有亲缘关系的进程间使用,因为管道 传递数据的单向性,管道又称为半双工管道.进程的亲缘关系通常是指父子进程关系. 管道的特点决 ...
- 详解linux进程间通信-管道 popen函数 dup2函数
前言:进程之间交换信息的唯一方法是经由f o r k或e x e c传送打开文件,或通过文件系统.本章将说明进程之间相互通信的其他技术-I P C(InterProcess Communication ...
- Linux 进程间通信(管道、共享内存、消息队列、信号量)
进程通信 : 不同进程之间传播或交换信息 为什么要进程通信呢? 协同运行,项目模块化 通信原理 : 给多个进程提供一个都能访问到的缓冲区. 根据使用场景,我们能划分为以下几种通信 ...
- linux进程间通信-管道
一 管道的局限性 管道有两个局限性:(1)他是半双工(即数据只能在一个方向上流动).(2)它只能在具有公共祖先的进程之间使用.一个管道由一个进程创建,然后该 进程调用fork,此后父子进程之间就可该管 ...
- Linux 进程间通信(二) 管道
Linux 进程间通信-管道 进程是一个独立的资源分配单位,不同进程之间的资源是相互独立的,没有关联,不能在一个进程中直接访问另一个进程中的资源.但是,进程不是孤立的,不同的进程之间需要信息的交换以及 ...
- Linux进程间通信(IPC)机制总览
Linux进程间通信 Ø 管道与消息队列 ü 匿名管道,命名管道 ü 消息队列 Ø 信号 ü 信号基础 ü 信号应用 Ø 锁与信号灯 ü 记录锁 ü 有名信号灯 ü 无名信号灯(基 ...
随机推荐
- Deeplab
Deeplab系列是谷歌团队的分割网络. DeepLab V1 CNN处理图像分割的两个问题 下采样导致信息丢失 maxpool造成feature map尺寸减小,细节信息丢失. 空间不变性 所谓空间 ...
- java架构之路-(netty专题)netty的编解码(出入战)与粘包拆包
上次回归: 上次博客我们主要说了netty的基本使用,都是一些固定的模式去写的,我们只需要关注我们的拦截器怎么去写就可以了,然后我们用我们的基础示例,改造了一个简单的聊天室程序,可以看到内部加了一个S ...
- 第2章 Java并行程序基础(三)
2.8 程序中的幽灵:隐蔽的错误 2.8.1 无提示的错误案例 以求两个整数的平均值为例.请看下面代码: int v1 = 1073741827; int v2 = 1431655768; Syste ...
- 第2章 Java并行程序基础(一)
2.1 有关线程你必须知道的事 进程是系统进行资源分配和调度的基本单位,是程序的基本执行实体. 线程就是轻量级进程,是程序执行的最小单位. 线程的生命周期,如图2.3所示. 线程的所有状态都在Thre ...
- 1276:【例9.20】P2758 编辑距离
题目传送门[(https://www.luogu.com.cn/problem/P2758)] 题目描述 设A和B是两个字符串.我们要用最少的字符操作次数,将字符串A转换为字符串B.这里所说的字符操作 ...
- 【算法】混合流体模拟demo
展示一个流体模拟算法的实现 地址:http://www.iqiyi.com/w_19rzs1anol.html 采用C++编写,Blender渲染. 截图 参考文献 REN, B., LI, C., ...
- KVM性能优化之CPU优化
前言 任何平台根据场景的不同,都有相应的优化.不一样的硬件环境.网络环境,同样的一个平台,它跑出的效果也肯定不一样.就好比一辆法拉利,在高速公路里跑跟乡村街道跑,速度和激情肯定不同... 所以,我们做 ...
- 【转】Android之四大组件、六大布局、五大存储
文章来自:http://blog.csdn.net/shenggaofei/article/details/52450668 一.四大组件: Android四大组件分别为activity.servic ...
- 7个有用的JS技巧
就如其他的编程语言一样,JavaScript也具有许多技巧来完成简单和困难的任务. 一些技巧已广为人知,而有一些技巧也会让你耳目一新. 让我们来看看今天可以开始使用的七个JavaScript技巧吧! ...
- make: *** No targets specified and no makefile found. Stop.错误
# make make: *** No targets specified and no makefile found. Stop. # yum install gcc gcc-c++ gcc-g77 ...