Open Jaf932074323 opened 2 years ago
这是因为接收方来不及收取消息,会造成消息堆积。 目前消息队列总长度为255,超出长度,又过了100ms超时仍然堆积的情况,sender会通过force_push强行写入。 force_push强行写入会清理导致超时的receiver(因为可能意外崩溃或卡死,不能无限制的每次都等待),因此对接收来不及的receiver来说,相当于被踢了。 你的例子里,receiver并没有死,而是人为制造了100ms等待,因此receiver被踢了以后就无限等在那了。
你这个情况我后面考虑加个机制,当receiver被踢掉以后自己需要知道,这样recv就会直接退出了。
@mutouyun 这个是我在进程间通信时,遇到的问题。 因为发送端只管发送,速度非常快。而接收端还需要处理数据,速度就跟不上。 上图是我根据实际遇到的问题,写的一个问题复现demo。100ms等待就在模拟接收端处理数据。 force_push强行写入的话,会导致接收端掉包的情况。 有不有同步发送功能呢,在发送的时候,等待接端接收到数据之后,发送函数再返回呢。或者每次发送的时候获取一下消息队列的状态,队列满的时候发送方阻塞等待一下。 另外有一个问题,开源库支持多发多收、单发多收,但是没有找到单发单收功能。 最后,非常感谢你们的开源库哟,方便了不少。
而接收端还需要处理数据,速度就跟不上。
这是不行的,这样必然会导致消息丢失。 正确的做法是,你需要自己做一层隔离,接收消息应该放到你自己的内存队列里做cache,处理的时候从cache中取。
等待接端接收到数据之后,发送函数再返回 每次发送的时候获取一下消息队列的状态,队列满的时候发送方阻塞等待一下
如上这种逻辑,不是ipc通讯组件需要考虑的,需要的是类似 rpc 的逻辑。 你需要基于ipc自己实现一套,或者直接使用现成的rpc框架,比如: https://github.com/alephzero/alephzero https://github.com/eclipse-iceoryx/iceoryx https://github.com/qicosmos/rest_rpc
另外有一个问题,开源库支持多发多收、单发多收,但是没有找到单发单收功能
参见:https://github.com/mutouyun/cpp-ipc/wiki/Tutorial#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8A%9F%E8%83%BD
发送端在堵塞的时候其实是有等待的,你可以在 include/libipc/def.h 中配置 default_timeout,或者在 send 调用的时候传入 timeout(单位ms)
当发送方速度很快,接收方跟不上的时候,接收方会异常阻塞卡死,怀疑是同步控制有问题。 在win平台下,vs2019编译环境,64位debug,创建控制台项目,有如下源代码:
include
include
include
include
include "libipc/ipc.h"
constexpr char const name[] = "ipc-chat"; ipc::channel sender{ name, ipc::sender }; ipc::channel receiver{ name__, ipc::receiver };
int main() { std::thread receiver([]() { std::cout << " Start recv.\n";
}
执行一段时间后,发送会提示: fail: send, there is no receiver on this connection. 在暂停断点调试,会发现receiver接收线程阻塞在了cpp-ipc\src\libipc\platform\waiterwin.h文件的45行处,永远不退出了,阻塞代码: switch ((ret = ::WaitForSingleObject(h, ms))) {