进程间通信(IPC)

Posted 五个板栗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程间通信(IPC)相关的知识,希望对你有一定的参考价值。

一、什么是进程间通信?       

       在linux环境下,进程地址空间是相互独立的,每个进程都有各自不同的用户地址空间。任何一个进程的全局变量在另外一个进程中都是看不到的,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程把数据从用户空间拷到内核缓冲区,另一个进程再从内核缓冲区把数据拷走,内核提供的这种机制就称为进程间通信。(InterProcess Communication,简称IPC)。

进程间通信(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 失败:-1 errno
  • 函数实现
#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;

进程间通信(IPC)_管道_02

通信前:

进程间通信(IPC)_管道_03

通信后:

进程间通信(IPC)_管道_04

管道的读写行为

1.读管道:

  • 管道中有数据,read返回实际读到的字节数。
  • 管道中无数据,管道写端被全部关闭,read返回0(类似读到文件末尾);写端没有全部关闭,read阻塞等待(之后可能有数据传达,此时会让出cpu);

2.写管道:

  • 管道读端全部被关闭,进程异常终止(可以使用捕捉SIGPIPE信号,让进程不终止)。
  • 管道读端没有全部关闭,管道已满,write阻塞;管道未满,write将写入数据,并返回实际写入的字节数。


以上是关于进程间通信(IPC)的主要内容,如果未能解决你的问题,请参考以下文章

Android中的IPC进程通信方式第三篇

Android中的IPC进程通信方式第二篇

Android中的IPC进程通信方式第五篇

Linux 进程间通信(IPC)

Linux进程间通信---管道

ipc (进程间通信