Linux IPC简单总结
---------------
##消息传递##
- 信号: 非亲缘,传递信息少,只能是控制信息而不是数据信息
- 管道: 要亲缘,无边界字节流,先进先出,消耗掉就没了,没有窥探功能MSG_PEEK
- FIFO: 非亲缘,无边界字节流,先进先出,消耗掉就没了,没有窥探功能MSG_PEEK
- Socket: 非亲缘,边界可有可无,效率较低
- Unix Socket: 非亲缘,边界可有可无,比Socket的效率高,比共享内存的效率低
- 消息队列:无亲缘,有边界,比共享内存的效率低,有优先级,消耗掉就没了,没有窥探功能MSG_PEEK
分为Posix和System V两种,posix消息队列和System V的消息队列的区别:posix消息队列支持notify,
每次拿的都是优先级最高的消息,posix可以对应于一个文件(随文件系统进行持久化的),通过 fstat 该
文件得到消息队列的信息,而 System V 可以指定每次拿哪一优先级的消息,有 ipc_perm 结构来描述。
- 共享内存
效率最高,缺点是需要自行处理同步
匿名共享内存:System V 和Posix用shm_open打开的都是匿名的,随内核持续
有名共享内存:Posix用open打开的有名的,可随文件系统持续,随文件持续
Posix的在使用时可以扩张,而System V在创建时就定下来了。
##同步机制##
- 互斥量:只有两种状态(信号量有>2的状态),解锁只能有上锁的进程完成(信号量不用)
- 条件变量:如果没有线程在条件变量上等信号,那么信号会丢失(信号量不会丢失,因为有一个与之关联的状态)
- 读写锁:与互斥量不同的,读锁可以加多次,写锁只能加一次。要注意读写饥饿问题。
- 信号量:SystemV是匿名的,Posix有有名和匿名两种。有名的总能在不同进程间共享,匿名的需要信号量在共享内存中才可以。Posix有名信号可以随文件持久,也就是没解锁,下次启动内核或进程还是没解锁的。
- 记录上锁:互斥量(条件变量+读写锁)只能在同一进程或锁定义在共享内存的进程间使用。记录上锁可以用于完全没关系的进程。分劝告性记录上锁和强制性记录上锁。劝告性的加了写锁是不影响读的,加了读锁是不影响写的;强制性锁则使内核检查每个read和write请求,以验证其操作不会干扰由某个进程持有的某个锁。对于通常的阻塞式描述字,与某个强制性锁冲突的read或write将把调用进程投入睡眠,直到该锁释放为止。对于非阻塞式描述字,与某个强制性锁冲突的read或write将导致它们返回一个EAGAIN错误。记录上锁在进程结束后没有被及时显式解锁,内核也会解锁。System V对这个功能是可选的,而其他的不会。
##IPC的优缺点###
- 管道( pipe ):数据只能单向流动,而且只能在具有亲缘关系的进程间使用。好处是方便,在fork一个子进程时,父进程往往是用pipe来获取子进程的输出。
- 有名管道 (named pipe),也被称为FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
- 消息队列( message queue ) :消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。通信的两个进程之间可以是完全无关的进程,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。比FIFO更有优势。但很少见到有用消息队列的。
- 共享内存( shared memory ) :优点是快,缺点是需要程序员做同步,对程序员的要求相对较高。mmap(posix)可以对文件进行映射,而shm*只能对内存进行映射。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。