进程间通信方式
每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,进程B再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。
1 管道模型
1
2
3
4
5
6
7
8 >
> /** fd[1]的输出是fd[0]的输入。
> * @return 0:成功 1:出错
> * @param fd[0] 管道的读端
> * @param fd[1] 管道的写端
> */
> int pipe (int fd[2]);
>
1.1 匿名管道( Anonymous Pipes)
只能在管道创建进程及其后代之间通信
1 | $ ps -ef | grep 关键字 | awk '{print $2}' | xargs kill -9 |
管道父子通信的步骤:
- 父进程创建管道,得到两个文件描述符指向管道两端
- 父进程fork出子进程,子进程也有两个文件描述符指向同一管道
- 父进程关闭
fd[0]
,子进程关闭fd[1]
(只能单向通信)
管道兄弟通信步骤:
在上面的最后一步改为父进程关闭
fd[1]
,子进程关闭fd[0]
,再fork另外一个子进程Bshell保留的读取端的
fd[0]
也被复制到了子进程B中,只要父进程关闭fd[0]
,管道双方就换成了A 和B
1 |
|
1.2 命名管道
通过管道文件名, 可以在任意进程之间通信
1 | $ mkfifo hello |
实际上是内核里面的一串缓存
2 消息队列
信息复制两次,额外的CPU消耗;不合适频繁或信息量大的通信;
3 共享内存
无须复制,共享缓冲区直接付附加到进程虚拟地址空间,速度快;但进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决;
4 信号量
常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段
5 信号
不适用于信息交换,更适用于进程中断控制,比如非法内存访问,杀死某个进程等;
6 套接字
略,使用参考ICMP重定向实验