老生长谈:进程间通信

进程间通信方式真可谓老生长谈了, 但是进程间通信都有哪些,又都在哪应用呢? 好吧 不多哔哔,为自己科普起来

1 无名管道通信

Pipe

管道是 UNIX 系统 IPC 的最古老的形式,所有的 UNIX 系统都提供管道机制,如果你使用过 shell 中的管道,应该不会默认,例如

1
ps -aux | grep "xxx"

这个意思是将 ps -aux 的输出作为 grep xxx 的输入,通过管道可以将两个进程连接起来,功能非常强大,但是有名管道与 shell 的管道有些区别。

2有名管道通信

Fifo

命名管道(named pipe)又被称为先进先出队列(FIFO),是一种特殊的管道,存在于文件系统中。命名管道与管道非常类似,但是又有自身的显著特征:

命名管道可以用于任何两个进程间的通信,而不限于同源的两个进程。

命名管道作为一种特殊的文件存放在文件系统中,而不是像管道那样存放在内核中。当进程对命名管道的使用结束后,命名管道依然存在于文件系统中,除非对其进行删除操作,否则该命名管道不会自行消失。

和管道一样,命名管道也只能用于数据的单向传输,如果要用命名管道实现两个进程间数据的双向传输,建议使用两个单向的命名管道。

3信号通信

Signal

信号(Signals)是Unix、类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方式。

它是一种异步的通知机制,用来提醒进程一个事件已经发生。当一个信号发送给一个进程,

操作系统中断了进程正常的控制流程,此时,任何非原子操作都将被中断。

如果进程定义了信号的处理函数,那么它将被执行,否则就执行默认的处理函数。

信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。也可以简单理解为信号是某种形式上的软中断。

例如:kill 命令发出

4消息队列通信

Message Queue

消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。

每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构。

我们可以通过发送消息来避免命名管道的同步和阻塞问题。

但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制。

5信号量通信

Semphone

简单说一下信号量的工作机制(因为真的很简单),可以直接理解成计数器(当然其实加锁的时候肯定不能这么简单,不只只是信号量了 )

信号量会有初值(>0),每当有进程申请使用信号量,通过一个P操作来对信号量进行-1操作,

当计数器减到0的时候就说明没有资源了,其他进程要想访问就必须等待(具体怎么等还有说法,比如忙等待或者睡眠),

当该进程执行完这段工作(我们称之为临界区)之后,就会执行V操作来对信号量进行+1操作。

6共享内存通信

Share Memory

共享内存,顾名思义,就是两个或多个进程都可以访问的同一块内存空间,一个进程对这块空间内容的修改可为其他参与通信的进程所看到的。

显然,为了达到这个目的,就需要做两件事:一件是在内存划出一块区域来作为共享区;另一件是把这个区域映射到参与通信的各个进程空间。

通常在内存划出一个区域的方法是,在内存中打开一个文件,若通过系统调用mmap()把这个文件所占用的内存空间映射到参与通信的各个进程地址空间,则这些进程就都可以看到这个共享区域,进而实现进程间的通信。

7套接字通信

Socket

这个不必多说。。。