一个自用的进程间通信库(二)

来源:互联网 发布:mac 战网 改台服 编辑:程序博客网 时间:2024/06/10 09:26

        要使用这个库,最基本的就是首先要给自己创建一个信箱。信箱创建时会带一个返回值,是内部生成的信箱ID,因为整型的比较速度远远快过字符串,所以也得支持根据ID进行发送,而且共享内存中的信箱时根据ID排序的,可以根据ID用二分查找进行搜索,现在的问题是当通过名字进行查找时,如果信箱的数量很多,那查找速度就太令人遗憾了,因为信箱是存放在共享内存中的,而且信箱的创建和销毁时动态的,所以本地进程无法存储其它信箱的地址,否则你刚存一个,别人销毁又创建一个,这时通过ID发送会失败,通过名称发送会成功,通过地址发送会傻眼。现在可用的方法一个是在共享内存中通过信箱名称再建一个索引表,也排下序,信箱创建和销毁的时候都会更新这个索引表。另一个方法是提供一种使用大量信箱的手段,根据分类在共享内存中提供一个类似于指针的间接层,有这个名称的信箱则“指针”(不是真的指针)指向真正的信箱地址,若没有就是0呗,具体实现是在共享内存的头部保留16*1024个int的大小,默认都为0,如果根据名称规则创建信箱,则会获得其中一个int指向实际分配的信箱,这个速度理论上应该很快,因为几乎不需要进行查找,但对名称有要求。后来想想,还是两种方式都提供下吧,再差也能获得一个二分查找的效率,只是需要浪费部分共享内存的空间,对照表简单定义成32字节的名称和int的序号,一般40字节左右,1000个信箱也不超过40k,10000个信箱也就是多耗费400k共享内存的空间,只要我们在创建共享内存的时候留出适当的余量,这应该不是问题。

        发送数据时需要有3个参数,前两个参数很好理解,一个是目标信箱名称,一个是自己的名称。为什么参数里面需要填自己的名称,系统为什么不能自动获取呢,这还真是个问题,因为我们的信箱支持进程内部通信,也就是说一个进程可以创建任意多的信箱,那么多信箱都在同一个进程,现在就没法知道哪个是你要用的了,不得已只能出此下策。第三个参数就是发送数据了,这个参数的定义很简单,一个数据指针加一个数据长度。

        数据发送时,先在本地查找对方,如果对方就在本地,那就不折腾了,也不用锁定共享内存,内部消化了。如果不在本地,则尝试锁定共享内存,成功后根据名称或ID查找对方信箱地址,找到后,在共享内存中分配发送数据所需的空间,将数据插入到信箱数据链的末尾。到这里windows和linux下的操作几乎都相同,下面就略有点区别了,windows下需要找到对方信箱所在进程所创建的event,linux下需要找到对方信箱所在进程在共享内存中所创建的pthread_mutex_t和pthread_cond_t,发送事件或信号通知对方,解锁共享内存。

       接收方的线程接收到数据信号后,尝试锁定共享内存,成功后将本地所有的信箱内的数据按照先入先出的规则读出保存到本地,然后解锁共享内存,重置数据信号。接下来就可以慢慢处理本地的数据了,好了,看看linux下面运行的效果,看上去还可以。几十、几百、甚至更多信箱的情况只能留到以后再测了。

原创粉丝点击