今天我们来聊聊进程间的相互通信
进程间的相互通信大体可以分成4种方式,分别是管道,信号,消息队列和共享内存,接下来我们一个一个说。
- 管道
进行间的管道通信是最简单的一种方式,它是一种半双工的工作模式,一次只能由一个节点传向另一个节点,两个节点间不可以同时通信。管道只存在于内存中的文件,如果操作这个文件,那么需要两个已经打开的文件,这两个文件就是管道的两端,也叫“句柄”。熟悉linux编程的同学应该对“句柄”这个词不陌生,它其实保存了文件打开的相关信息。当一个管道建立后,一个进程(写进程)在管道的尾部写入数据,另一个进程(读进程)从管道的头部读出数据。数据被一个进程读出后,将从管道中删除,因此其他进程将不能够再读到这些数据,因此管道的数据是先进先出的。管道有可以分成无名管道和有名管道。
无名管道存在于父进程与子进程之间,即无名管道的数据只能在父进程与子进程之间传递
有名管道则容许不同进程(没有亲缘关系)也能交换数据
- 信号
信号是用来通知或者接收进程某个事件的发生。信号有点类似于嵌入式开发中的中断模式,即进程中某个事件发生后,就发送一个信号通知另一个进程。当进程接到这个信号后,会启动指定的处理程序,当进程没有给这个信号指定处理程序时,内核会有相应的缺省动作,包括异常中止,退出,忽略,停止和继续。
这里要注意一下信号与信号量的区别,信号量其实是一个计数器,可以用来控制多个进程对共享资源的访问。它常常被用作一种锁机制,防止进程正在访问共享资源时,其他进程也访问该资源。信号量主要作为进程间以及同一个进程内不同线程的同步方式。
- 消息队列
上面提到的无论时管道还是信号,都有一个缺点,就是信息承载量不大,如果我们想要发送大量信息时,上面的方法就有点力不从心,因此引入了另一种通信方式——信息队列。信息队列其实是消息的列表,包括Posix消息队列和system信息队列,前者常用于线程,后者常用于进程。有写权限的进程可以向消息队列中添加消息,而有读权限的进程则可以读走消息队列中的消息。
- 共享内存
共享内存是最快,最高效的IPC方式,共享内存可以让多个进程访问同一片内存空间,其实现方式是映射一段能够被其他进程所访问的内存空间,这段内存由一个进程创建,但是多个内存都可以访问。共享内存往往和其他通信方式,例如信号量,管道等同时使用,从而实现进程间的信息共享与同步。
另外还有一种方式是套接字,但我更多的认为它是一种网络的通信方式了,包块套接字的创建,绑定,监听等等,有兴趣的同学可以自行学习。
以上就是今天的全部内容。与您共勉