进程间通信---管道
2018-03-12 20:18
239 查看
我们知道,进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区。但是,系统空间却是“公共场所”,所以内核显然可以提供这样的条件。所以进程之间交换数据时在内核进行,通俗的说A进程把数据拷贝到内核,B进程从内核中把数据读走,我们把内核提供的这种机制叫做进程间通信,(IPC)。
一、管道(pipe)
管道是Unix中最古老的进程间通信的形式。 我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”。
管道是一种基本的ipc机制,由pipe函数创建,如下:
调用pipe函数时在内核中开辟一块缓冲区(管道)用于通信,它有一个读端和一个写端。
fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
pipe函数调用成功返回0,失败返回-1。
二、如何实现进程间通信
(1)首先父进程调用pipe开通管道,得到两个文件描述符指向管道的两端
(2)父进程通过fork创建子进程,那么同样的子进程也有两个文件描述符指向管道的两端
(3)父进程关闭fd[0],子进程关闭管道fd[1],这样父进程向管道写数据,子进程向管道读数据,这就实现了进程的通信.
注:图中0、1、2分别指的是标准输入,标准输出,标准出错
三、匿名管道和命名管道
1、匿名管道
值得说明的是,匿名管道只能实现亲缘关系进程之间通信,而不能实现任意两个本地进程之间的通信
使用,正如上图所示:
在父进程中,首先创建这个匿名管道,然后fork创建子进程,关闭子进程的读端,子进程只能进行写,子进程向这个匿名管道里面写数据,父进程向这个匿名管道里面读数据,以此来实现进程间的通信。
实现:
2、命名管道
如果想在不相关的进程之间通信,可以使用FIFO文件来做这项工作,它经常被称为命名管道 。
FIFO总是按照先进先出的原则工作,也就是第一个被写入的数据将首先从管道中读出 。
那么如何创建呢?
方法一:命名管道可以从命令行创建,方法是使用命令:
$ mkfifo filename
方法二:从在程序使用系统函数创建,函数有:
int mkfifo(const char *filename,mode_t mode);
以mkfifo为例:
eg-用命名管道实现server&client通信 :
(1)、编写Makefife文件:
(2)、server.c用来读数据(读端)
(3)、client.c向管道写数据(写端):
结果:
一、管道(pipe)
管道是Unix中最古老的进程间通信的形式。 我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”。
管道是一种基本的ipc机制,由pipe函数创建,如下:
调用pipe函数时在内核中开辟一块缓冲区(管道)用于通信,它有一个读端和一个写端。
fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
pipe函数调用成功返回0,失败返回-1。
二、如何实现进程间通信
(1)首先父进程调用pipe开通管道,得到两个文件描述符指向管道的两端
(2)父进程通过fork创建子进程,那么同样的子进程也有两个文件描述符指向管道的两端
(3)父进程关闭fd[0],子进程关闭管道fd[1],这样父进程向管道写数据,子进程向管道读数据,这就实现了进程的通信.
注:图中0、1、2分别指的是标准输入,标准输出,标准出错
三、匿名管道和命名管道
1、匿名管道
值得说明的是,匿名管道只能实现亲缘关系进程之间通信,而不能实现任意两个本地进程之间的通信
使用,正如上图所示:
在父进程中,首先创建这个匿名管道,然后fork创建子进程,关闭子进程的读端,子进程只能进行写,子进程向这个匿名管道里面写数据,父进程向这个匿名管道里面读数据,以此来实现进程间的通信。
实现:
#include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<unistd.h> #include<string.h> #include<sys/wait.h> int main() { int fds[2] ={0}; if(pipe(fds)<0) { perror("pipe"); return 1; } pid_t id =fork(); if(id==0) { //子进程写 close(fds[0]); char *msg ="hello pipe,i am a child!"; while(1) { write(fds[1],msg,strlen(msg)); sleep(1); } exit(0);//退出 } else{ //父进程读 close(fds[1]); char buf[1024]; while(1) { ssize_t ret = read(fds[0],buf,sizeof(buf)-1); if(ret>0) { buf[ret-1]=0; printf("client->father:%s\n",buf); } } pid_t tmp =wait(NULL); } return 0; }
2、命名管道
如果想在不相关的进程之间通信,可以使用FIFO文件来做这项工作,它经常被称为命名管道 。
FIFO总是按照先进先出的原则工作,也就是第一个被写入的数据将首先从管道中读出 。
那么如何创建呢?
方法一:命名管道可以从命令行创建,方法是使用命令:
$ mkfifo filename
方法二:从在程序使用系统函数创建,函数有:
int mkfifo(const char *filename,mode_t mode);
以mkfifo为例:
int main(int argc, char *argv[]) { mkfifo("p2", 0644); return 0; }
eg-用命名管道实现server&client通信 :
(1)、编写Makefife文件:
(2)、server.c用来读数据(读端)
(3)、client.c向管道写数据(写端):
结果:
相关文章推荐
- 进程间通信(二):利用匿名管道
- Linux环境进程间通信(一)管道和有名管道
- 进程间通信——管道
- 进程间通信——管道部分
- 1.6 进程间通信方式之有名管道
- 进程间通信(IPC)之管道家族
- UNIX环境高级编程学习之第十五章进程间通信 - 通过匿名管道实现父子进程同步
- 【Linux】管道实现进程间通信
- linux系统编程之管道实现父系进程间通信
- 进程间通信的方式-信号、管道、消息队列、共享内存
- 进程间通信之管道
- linux内核之进程间通信(1)——管道
- 进程间通信--管道
- 进程间通信之管道
- Linux进程间通信(IPC)之二——命名管道(FIFO)
- 进程间通信的方式——信号、管道、消息队列、共享内存
- 进程间通信——管道代码实现
- 网络编程(14)—— 进程间通信-管道pipe
- Linux进程间通信-FIFO(命名管道)
- 进程间通信之双管道