进程间通信的发/收/回复的健壮实现
通过使用发/收/回复将共同合作的线程与进程作为一个团队来构建一个UNIX应用程序的架构就会得到一个同步通知的系统。进程间通信就为这个系统的特殊转型而产生的,而不是在其后。
异步系统的一个重要问题就是事件通知需要依靠信号处理器才能运行。异步的进程间通信将难于进行彻底的系统运行测试,并不能够确保不论信号处理器怎样,处理工作能够如预想的那样运行。应用程序一般都是依赖一个确定的起始点的“窗口”,在这个窗口中信号的延迟是可以忍受的,来避免出现这种情况。
如果使用基于发/收/回复的同步、无队列的系统架构,健壮的应用程序架构就能够很容易的实现并交付。
使用队列IPC、共享内存以及其他同步原的各种组合来构建应用程序的另外一个关键问题就是如何避免死锁状态。例如,线程A在线程B释放复用体2之前不会释放复用体1,而且不幸的是线程B在线程A释放复用体1之前也不会释放复用体2,这时死锁就出现了。经常激活模拟工具来确保在系统运行时没有死锁的情况发生。
发/收/回复这些IPC原在遵守以下简单原则的话就能够构建无死锁的系统了:
- 永远不让两个线程互发;
- 一直使用继承的方式排列线程,只向继承树的上级发送。
第一条就避免了死锁情况发生,第二条则需要详细解释。合作的线程与进程的排列如下图所示:
在这里可以看到,任何级别的线程都不互相之间发送,只向其上层发送。
一个例子就是向数据库服务器进程发信的客户应用程序,它按序向文件系统经常发送信息。由于发送线程阻塞并等待回复,而目标线程没有发送阻塞就不会产生死锁。
但是,高层的线程如何提示底层线程它已经有了以前的操作请求的结果了?(假如底层线程在上一次发送之后不想继续等待回复结果。)
UNIX系统提供了一个非常灵活的架构,通过使用MsgDeliverEvent()这个内核调用来发布非阻塞的事件。所有异步服务都可以使用这种方式完成。
Related posts:
近期评论