进程间通信
进程间通信(IPC):操作系统为用户提供的集中进程进通信方式;因为进程之间具有独立性(每个进程都有自己的虚拟地址空间)无法直接通信,访问的都是自己的虚拟地址,而不是直接的访问物理内存,无法访问同一块区域,因此无法实现数据间的通信,所以操作系统给进程提供了几种通信方式:
数据传输-管道
共享内存
消息队列
信号量
网络
unix域套接字
管道
我们把一个进程连接到另一个进程发让一个数据流称为一个管道。一个进程要创建一个管道,操作系统会返回两个文件描述符,作为管道的操作句柄,这个管道因为在内核中没有标识符,因此无法被其他进程找到,只能通过子进程复制父进程的方式获取到管道的两个操作句柄,通过这种方式访问到相同的管道实现通信。
具有亲缘关系:只要能够通过复制父进程获取到管道操作句柄的进程都可以进行通信
概念
管道用于实现进程间的数据传输,它的本质原理是内核中的一块缓冲区,多个进程通过访问同一块缓冲区实现通信。
管道的分类
匿名管道和命名管道
匿名管道
概念
内核中的缓冲区没有标识符,只能用于具有亲缘关系的进程间通信;
如何创建匿名管道
int pipe(int pipefd[2]);
pipefd[2]---->具有两个int型节点的数组的首地址,用于接收创建管道返回的操作句柄;
pipefd[0]
:用于从管道中读取数据;
pipefd[1]
:用于向管道中写入数据;
只能进入读/写其中一个功能,使用时如果不使用哪一端就进行关闭。
返回值:成功返回0,失败返回-1;
命名管道
概念
是内核中的一块缓冲区,这块缓冲区具有标识,能够被其他进程通过同一个标识符找到相同的管道,因此可以实现同一主机上的任意进程间的通信,而这个标识符实际上是一个管道文件。
创建命令管道
- 通过命令:mkfifo创建管道文件
- 代码中的操作:int mkfifo(const char *filename,mode_t mode);
filename
:管道文件名称;
mode
:管道文件权限;
成功返回0,失败返回1;
命名管道打开的特性
- 如果以只读的方式打开,则会发生阻塞,直到文件以被写的方式打开;
- 如果文件以只写的方式打开,则会阻塞,直到文件以被读的方式打开;
下面我们写一个简单的例子做以演示:
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/stat