进程间通信(IPC)

寸阳分阴须爱惜,休负春色与时光。这篇文章主要讲述进程间通信(IPC)相关的知识,希望能为你提供帮助。
一、什么是进程间通信?                在linux环境下,进程地址空间是相互独立的,每个进程都有各自不同的用户地址空间。任何一个进程的全局变量在另外一个进程中都是看不到的,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程把数据从用户空间拷到内核缓冲区,另一个进程再从内核缓冲区把数据拷走,内核提供的这种机制就称为进程间通信。(InterProcess Communication,简称IPC)。

二、进程间通信的方式在进程间完成数据传递需要借助操作系统提供一些特殊的方法,以前有文件、管道、信号、共享内存、消息队列、套接字、命名管道等等。随着计算机技术的不断发展与成熟,现如今常见的进程间通信方式有:

  1. 管道——使用最简单,但需要有血缘关系
  2. 信号——开销最小
  3. 共享映射区——无血缘关系
  4. 本地套接字——最稳定,但是实现较为复杂
三、最基本的IPC机制—管道
mkfifo 管道名
//创建命名管道可以作用于两个不具有血缘关系的两个进程之间

管道的原理:实际上是内核使用环形队列机制,借助内核缓冲区(4k)实现。
管道的特征:
  1. 本质是一个伪文件,实际上为内核缓冲区。
  2. 由两个文件描述符引用,一个表示读端,一个表示写端。
  3. 规定数据从管道的写端流入管道,从读端流出。
管道的局限性:
  1. 数据不能进程自己写,自己读。
  2. 管道中数据不可反复读取,一旦读走,管道不再存在。
  3. 采用半双工通信方式(通信方式有:单工、半双工、全双工),数据只能在单方向上流动。
  4. 只能在有公共祖先的进程间使用。
创建管道:pipe函数
  • 函数原型:int pipe(int pipefd[2]); //创建并打开管道,两个端口都打开了。
  • 参数:fd[0]; //读端 fd[1]; //写端
  • 返回值:成功:0失败:-1errno
  • 函数实现
#include < stdio.h>
#include < unistd.h>
#include < stdlib.h>
#include < string.h>
#include < errno.h>
#include < pthread.h>
void sys_err(const char *str)

perror(str);
exit(1);

int main()

int ret;
int fd[2];
pid_t pid;
char buf[1024];

char *str="hello pipe\\n";
ret=pipe(fd);
if(ret==-1)
sys_err("pipe error");
pid=fork();
if(pid> 0)

close(fd[0]); //关闭读端
write(fd[1],str,strlen(str));
close(fd[1]);

else if(pid==0)

close(fd[1]); //子进程关闭写端
ret=read(fd[0],buf,sizeof(buf));
write(STDOUT_FILENO,buf,ret);
close(fd[0]);

return 0;


通信前:

通信后:

管道的读写行为
1.读管道:
  • 管道中有数据,read返回实际读到的字节数。
  • 管道中无数据,管道写端被全部关闭,read返回0(类似读到文件末尾);写端没有全部关闭,read阻塞等待(之后可能有数据传达,此时会让出cpu);
2.写管道:
  • 管道读端全部被关闭,进程异常终止(可以使用捕捉SIGPIPE信号,让进程不终止)。
  • 管道读端没有全部关闭,管道已满,write阻塞;管道未满,write将写入数据,并返回实际写入的字节数。
【进程间通信(IPC)】


    推荐阅读