进程间通信(IPC)
Posted 五个板栗
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程间通信(IPC)相关的知识,希望对你有一定的参考价值。
一、什么是进程间通信?
在linux环境下,进程地址空间是相互独立的,每个进程都有各自不同的用户地址空间。任何一个进程的全局变量在另外一个进程中都是看不到的,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程把数据从用户空间拷到内核缓冲区,另一个进程再从内核缓冲区把数据拷走,内核提供的这种机制就称为进程间通信。(InterProcess Communication,简称IPC)。
二、进程间通信的方式
在进程间完成数据传递需要借助操作系统提供一些特殊的方法,以前有文件、管道、信号、共享内存、消息队列、套接字、命名管道等等。随着计算机技术的不断发展与成熟,现如今常见的进程间通信方式有:
- 管道——使用最简单,但需要有血缘关系
- 信号——开销最小
- 共享映射区——无血缘关系
- 本地套接字——最稳定,但是实现较为复杂
三、最基本的IPC机制—管道
mkfifo 管道名
//创建命名管道可以作用于两个不具有血缘关系的两个进程之间
管道的原理:实际上是内核使用环形队列机制,借助内核缓冲区(4k)实现。
管道的特征:
- 本质是一个伪文件,实际上为内核缓冲区。
- 由两个文件描述符引用,一个表示读端,一个表示写端。
- 规定数据从管道的写端流入管道,从读端流出。
管道的局限性:
- 数据不能进程自己写,自己读。
- 管道中数据不可反复读取,一旦读走,管道不再存在。
- 采用半双工通信方式(通信方式有:单工、半双工、全双工),数据只能在单方向上流动。
- 只能在有公共祖先的进程间使用。
创建管道:pipe函数
- 函数原型:int pipe(int pipefd[2]);//创建并打开管道,两个端口都打开了。
- 参数:fd[0];//读端 fd[1];//写端
- 返回值:成功:0 失败:-1 errno
- 函数实现
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)的主要内容,如果未能解决你的问题,请参考以下文章