Unix System V 中的三种进程间通信机制:
消息队列
信号量(信号灯)
共享内存
这几个System V IPC 对象的访问权限是对象创建者通过系统调用设定的.访问这些System V IPC 对象首先要经过权限检查,就如同访问文件要经过权限检查一样.
一个进程只有通过系统调用向内核传递一个唯一的引用标识符才能访问这些资源.对象的引用ID是资源表中的一个索引,这个索引并不是直接的索引,而是要经过一些操作而产生的索引.System V IPC对象只能通过引用ID来引用.
在Linux中,描叙这几种System V IPC对象的数据结构中都包含一个ipc_perm结构,这个结构中包含了对象的所有者,创建者和进程的用户ID,组ID,还包括对象的访问权限和IPC对象关键字(键值).关键字用来确定System V IPC 对象的引用ID的位置.Linux中支持两种关键字: public 和private.若是public,那么系统中的所有进程都可以找到System VPIC对象的应用ID; 若是private,只有对象的创建者和同组有权查看System V IPC对象的引用ID.
System V IPC对象的统一属性,总结如下:
1)键key : 一个由用户提供的整数,用来标志这个资源的实例
2)创建者creator: 创建这个资源的进程的用户ID(UID), 组ID(GID)
3)所有者owner:资源的所有者的UID和GID
4)权限permisss:文件系统类型的权限.
消息队列
- 消息队列中的消息是一个结构, 它通常包含一个32位的类型值,其余的是数据区域.
- Linux维护一个消息队列的链表,称为msgque,链表中的每一个元素指向一个msqid_ds的数据结构, msqid_ds结构用来描叙消息.
- 每一个msqid_ds结构包含一个ipc_perm结构和一个指向消息的指针.另外,Linux还有记录队列的修改时间等信息. msqid_ds还包含两个等待队列,一个是写等待队列, 一个是读等待队列.
- 消息队列允许一个或者多个进程写消息,同样这个消息可以被一个或多个进程读取.
- 每一个消息都被标记为与应用程序相关的某种类型,这些内省在相互协调的进程间有统一的意义.
- Linux对消息的数量和长度都有限制,如果系统中没有足够的空间容纳新消息,那么要发送消息的进程将被加到消息队列的写等待队列中,当系统中有消息被读取时,消息队列有多的空间容纳新消息时,这个进程将被唤醒.
- 读取消息可以指定消息类型也可以指定读取队列中第一个消息.若没有消息符合读取进程的选择标准, 那么这个读取进程就加到消息队列的读等待列表中.当一个新消息写到消息队列中后,这个进程将被唤醒,重复上面的工作.
信号量
- 信号量是为了控制进程对资源的使用而发明的.
- 信号量可以用来实现一些同步协议.实现同步锁的功能
- 信号量是具有整数值的对象, 他的工作原理如下: 他支持两种原子操作P和V,P操作减少信号量的值,如果某一个信号量的值小于0,则操作阻塞; V操作增加信号量的值,如果结果值大于等于0,V操作就要唤醒一个等待进程.这两个操作是原子的,即他们是最小操作,不可分割.
共享内存
- 共享内存区域是被多个进程共享的一部分物理内存.进程可以把这些区域映射到它们地址空间的任一合适的虚拟地址范围.这些地址范围对每一个进程来说可以是不同的.隐射后,这些区域就可以像其他任何内存位置那样被访问,而不需要对它使用读read或写write调用.
- 共享内存机制提供了进程共享数据的最快方法.进程向共享内存区域写入数据,那么共享这个区域的所有进程可以立即看见共享区域中的新的内容.
- 如同访问所有System V IPC对象的方法一样,访问共享内存要通过关键字和访问权限来控制.访问权限和关键字是有共享内存的创建者来设置的.
- 一旦内存共享出来,Linux就不检查进程是如何使用这个共享内存了.所以,要安全的使用共享内存,必须依靠其他机制,例如使用信号量来同步访问共享内存.