进程间通信模式

来源:互联网 发布:js点击div上传图片 编辑:程序博客网 时间:2024/05/27 18:17

首先说一下单进程多线程设计。考虑一个消息队列的例子,线程1发送消息到消息队列,线程2从消息队列里面取数据。因为是单进程,两个线程可以引用同一个对象,所谓同一个对象是指两个对象的物理内存地址相同(不是虚拟内存,思维如果局限于虚拟内存会看不到跨进程和单进程的共同点)。

再说一下跨进程。进程1发送消息到消息队列,进程2从消息队列里面取消息。因为是跨进程,两个进程有各自的虚拟内存,所以不能引用同一个消息队列指针。怎么解决这个问题?可以通过加层,两个进程各引入一个代理。进程1发送消息到消息队列,消息队列实质操作代理,代理通过某种进程间通信方式(管道、共享内存或者套接字)发送到进程2的代理中,进程2代理再复制数据到消息队列。进程1发送数据到自己的消息队列就好像是直接发送数据到进程2的消息队列。代理作为屏蔽进程间通信的方式,使进程间通信就好像是同一个进程的不同线程直接通信一样。考虑双向通信,即进程1和进程2地位同等。

struct IObject{void SendMsg(void*);void RecvMsg(void*);};struct IProxy{static void* pFarObject;static vector<IObject*> aObject;static void SendMsg(void*);static void RecvMsg(void*);};

IObject调用SendMsg,实际调用IProxy的SendMsg。IProxy只有一个单例,pFarObject表示另外一段的引用,可以是套接字或者管道等;aObject是注册的本地的所有Object。RecvMsg可以用一个循环(也可以用Select等方式让内核通知,也可以用共享内存需要自己同步),始终查看pFarObject是否有消息。本端调用SendMsg,远端RecvMsg得到消息,调用每个aObject子对象的RecvMsg方法(也可以根据消息内容保护的接收对象来选择IObject对象),一次通信完成了。

如果是本地通信,可以用共享内存实现,两端的IProxy可以是同一个对象,即物理内存地址相同;如果是网络通信,可以用套接字。都可以屏蔽跨进程通信的事实。



原创粉丝点击