木头云

Results 99 comments of 木头云

确认了一下问题原因,recv退出的时候没有disconnet,因此send会继续发送一段时间,填满了预留的大message缓存池,导致后续连上来新的recv,send也无法利用缓存池快速发数据,而只能拆包,从而导致效率大大降低。 现有机制的解决办法:recv退出需要disconnect,这样send就知道连接断了不会继续发。 我考虑修改下现在的机制,目前有所谓的连接概念,但这其实是不太好的,ipc通道想确保qos有一些困难,而且会影响性能。我可能会把目前的连接去掉,直接在通道上收发,当消息写满了直接覆盖尚未取完的消息。 这样做缺点就是接收者可能会拿到被写了一半的数据,因为数据写入的原子性保证是需要加锁的。 后面的重构版本,我可能会放弃目前无锁队列的做法,因为对通用ipc来说,它相比加锁后的变长循环缓冲区,并没有太大优势。 想保证数据写入的原子性,不会读到写了一半的数据,现在其实也是有所谓的“锁”的,目前的代价就是写入需要等待最慢的那个读取操作。在最慢的读取进程未结束之前,哪怕其它读取进程都已经取走了所有数据,队列已空空如也,写入进程也无法写任何数据,所以现在的无锁队列本质上也只是个形式。 在希望保证数据写入的原子性的基础上,还不如直接加锁来得简单方便。

嗯……主要是因为目前实现基于的是共享内存,超时了就已经说明接收者卡死或者掉线了。 目前有一个机制是接收者卡死就把它踢掉,但也造成了容易误伤的bug。 目前的bug主要是在等超时的过程中,try_send是没有失败的,这段时间的发送数据是放在单独的共享内存缓冲池里,而这个池不像用来保持连接的循环队列,是可以循环使用的,目前的设计是需要接收者配合显式回收资源的。 这个设计不太好,我今天早上想到了一些新的优化方案,不过可能得周末再研究下。

感觉改起来有点麻烦。。我干脆在refactoring分支从头写好了。。

收发是怎样的?网状的,还是星形的?每个发送者同时也是接收者吗? 建议先把消息通讯链路画一个简图出来。

子进程之间会相互感知到么? 比如广播方式:父进程投递的消息,子进程A消费之后,B仍然会收到这条消息 或者消息队列:父进程投递到队列中,任意一个子进程均可以消费,消费掉了就没了 或者点对点通讯:父进程单独和每一个子进程通讯,每一条通道之间的消息是正交的

你可以用多发多收广播方式,自己过滤不需要的消息。 如果消息报文不大的话,建议采用父子点对点,需要用多发多收unicast模式(因为父和子都是既接收也发送,同时会有两个发送和接收者)。不过这样要求子进程个数(或者说目标)确定。

在 shm 模块里会使用引用计数进行生命周期管理(针对 linux,win会自动管理),因此正常退出的话,是最后一个退出的进程会自动清理共享内存。

我分别在 ubuntu20.04 + g++9.3.0 和 win10 + vs2019(16.8.4) 下测试了下,没出现你说的这种情况。 请问有简单的能复现的代码么?比如一个 main 加 ipc::channel sender__

感觉问题可能出在别的地方。 如果可以打印调试堆栈的话,建议捕捉一下程序崩溃信号,打印下backtrace

看起来是超时了。 目前ipc的发送、接收有概率出现拆包,由于存在一个bug #79,甚至有概率导致大消息一直拆包拼包,严重影响收发性能。 你的问题我先记下来了,等这两个月我忙完了项目再集中看一下……