Linux进程通信之匿名管道
进程间的通信方式
进程间的通信方式包括,管道、共享内存、信号、信号量、消息队列、套接字。
进程间通信的目的
进程间通信的主要目的是:数据传输、数据共享、事件通知、资源共享、进程控制等。
进程间通信之管道
管道(pipe):这种通讯方式有两种限制,一是半双工的通信,数据只能单向流动,二是只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
流管道(s_pipe): 去除了第一种限制,可以双向传输。
命名管道(name_pipe):克服了管道没有名字的限制,还允许无亲缘关系进程间的通信。
Linux进程间通信机制
管道的创建
pipe函数创建一个通信缓冲区,程序可以通过文件描述符fildes[0]和fildes[1]来访问这个缓冲区。返回值:成功返回0,错误返回-1。
#include<unistd.h>
int pipe(int fd[]);
管道的读写
参数fd为管道描述符,同文件描述符,可以使用文件I/O函数(close, read, write)对其进行操作。fd[0]为管道读端,fd[1]为管道写端。如不需要,可以关闭相应端的描述符。写入fd[1]的数据可以按照先进先出的顺序从fildes[0]中读出。
ssize_t read(fd[], void *buf, size_t count);
ssize_t write(fd[], void *buf, size_t count);
管道的实现
调用fork()创建两个子进程,使用系统调用pipe()建立一个管道,两个子进程分别向管道各写一句话:
Child process 1 is sending a message!
Child process 2 is sending a message!
而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。然后分别结束两个子进程。
注意事项:父进程和两个子进程间需要同步,使用waitpid()函数实现父进程等待子进程运行完毕后从管道中读取数据并打印。
由于fork函数让子进程完整地拷贝了父进程的整个地址空间,所以子进程都有管道的读端和写端。所以在相关进程中最好关掉不用的那一端。
要求“父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。”存在两个同步问题,两个子进程和父进程之间(先子写后父读)同步、子进程1和子进程2之间(先1写,再2写)。流程图如下所示:
管道实现进程间通信流程图
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h> int main()
{
int status;
pid_t p1;
pid_t p2;
int fd[];
char revbuf[]; int ret = pipe(fd); // 创建管道
if (ret == -) // 管道返回值为-1则失败
{
perror("Pipe error!\n");
exit();
} if ((p1 = fork()) == ) //子进程p1
{
char *child1 = "Child process 1 is sending a message!"; close(fd[]); //关闭管道读端
write(fd[], child1, strlen(child1)); //子进程1向管道写数据
}
else if (p1 > ) //父进程
{
waitpid(p1, &status, ); if ((p2 = fork()) == ) //子进程p2
{
char *child2 = "Child process 2 is sending a message!"; close(fd[]); //关闭管道读端
write(fd[], child2, strlen(child2)); //子进程2向管道写数据
}
else if (p2 > ) //父进程
{
close(fd[]); //关闭管道写端 // waitpid(p1, &status, 0);
read(fd[], revbuf, );
printf("The msg1: %s\n", revbuf);
waitpid(p2, &status, );
read(fd[], revbuf, );
printf("The msg2: %s\n", revbuf);
}
else //创建进程2失败
{
perror("Fork p2 error!\n");
exit();
}
}
else //创建进程1失败
{
perror("Fork p1 error!\n");
exit();
}
return ;
}
Linux进程通信之匿名管道的更多相关文章
- Linux 进程通信(无名管道)
无名管道 无名管道是半双工的,就是对于一个管道来讲,只能读,或者写. 无名管道只能在相关的,有共同祖先的进程间使用(即一般用户父子进程). 一个fork或者execve调用创建的子进程继承了父进程的文 ...
- Linux 进程通信(有名管道)
有名管道(FIFO) 有名管道是持久稳定的. 它们存在于文件系统中. FIFO比无名管道作用更大,因为他们能让无关联的进程之间交换数据. 管道文件一般用于交换数据. shell命令创建管道 一个she ...
- Linux进程通信----匿名管道
Linux进程通信中最为简单的方式是匿名管道 匿名管道的创建需要用到pipe函数,pipe函数参数为一个数组表示的文件描述字.这个数组有两个文件描 述字,第一个是用于读数据的文件描述符第二个是用于写数 ...
- linux进程通信之使用匿名管道进行父子进程通信
管道:是指用于连接一个读进程和一个写进程,以实现它们之间通信的共享文件,又称pipe文件. 管道是单向的.先进先出的.无结构的.固定大小的字节流,它把一个进程的标准输出和另一个进程的标准输入连接在一起 ...
- Linux进程通信——管道
管道(pipe)本质上是一种文件,管道通信本质上是通过读写文件通信,但是管道解决了文件的两个问题:限制管道大小,解决read()调用文件结束问题. 管道一个环形的缓冲区,通过两个进程以生产者/消费者的 ...
- linux进程通信之管道
1.介绍: 1)同一主机: unix进程通信方式:无名管道,有名管道,信号 system v方式:信号量,消息队列,共享内存 2)网络通信:Socket,RPC 2.管道: 无名管道(PIPE):使用 ...
- Linux 进程通信之管道
管道是单向的.先进先出的,它把一个进程的输出和还有一个进程的输入连接在一起.一个进程(写进程)在管道的尾部写入数据,还有一个进程(读进程)从管道的头部读出数据.数据被一个进程读出后,将被从管道中删除, ...
- 【转】如何基于linux进程通信设计方案
前言 linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的.而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在 ...
- Linux系统编程之匿名管道
1.进程间通信介绍 1.1 进程通信的基本概念 在之前我们已经学习过进程地址空间.Linux 环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间.任何一个进程的全局变量在另一个进程中都看不 ...
随机推荐
- css有关鼠标移动上去图片变透明度变化
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- jq案例中遇到的知识点总结(会飞的小鸟和三级联动)
1.会飞的小鸟 ,按键盘的上下左右键,小鸟会上下左右的飞 知识点:1.keyCode 键盘按键对应的数字 比如 左上右下键 对应 37 38 39 40: 2.小鸟的位置:var bBird=$(&q ...
- 文件夹选择之FolderBrowserDialog控件
应用程序可能只允许用户选择文佳夹而非文件,例如在播放MP3时,用户可能把所有的MP3放在一个文佳夹内,在添加时,只要选择添加这个文佳夹,将会把在这个文件内的所有MP3添加的播放器里.在这里对播放器来说 ...
- IsBackground对线程的重要作用
要点: 1.当在主线程中创建了一个线程,那么该线程的IsBackground默认是设置为FALSE的. 2.当主线程退出的时候,IsBackground=FALSE的线程还会继续执行下去,直到线程执行 ...
- FastDFS 基础知识
FastDFS是一个开源的轻量级分布式文件系统,它用纯C语言实现,支持Linux.FreeBSD.AIX等UNIX系统.它只能通过专有API对文件进行存取访问,不支持POSIX接口方式,不能mount ...
- 账户密码提示 jq简单事件
$(".username").focus(function(){ if($(this).val()=="请输入用户名"){ $(this).val(" ...
- Python的历史与基本知识入门
一.Python简介 1.1989年由"龟叔"Guido van Rossum在圣诞节期间打发无聊时间编写. 2.Python是一门弱类型解释性语言. 3.优点:代码简洁,明确,优 ...
- better-scroll 遇到的问题 1
备注:better-scroll 实现下拉,是父子层的结构,父层的第一个子元素,如果超出父容器,那么就可以实现下拉 问题: 今天在使用better-scroll实现下拉功能,遇到了一个问题 &quo ...
- ComponentOne、Spread、ActiveReports 5折起 加入惊喜惠
慧都十周年,GrapeCity也来共襄盛举,旗下三大产品产品线齐齐参与.界面控件套包ComponentOne.Excel表格控件Spread与报表开发工具ActiveReports,指定授权5折起加入 ...
- Android 给EditText添加下划线
在安卓高版本,默认是有下划线的,其默认下划线的颜色是由其主题颜色来控制的! 控制如下: <style name="AppTheme" parent="Theme.A ...