mutouyun / cpp-ipc

C++ IPC Library: A high-performance inter-process communication using shared memory on Linux/Windows.
Other
1.72k stars 334 forks source link

崩溃恢复问题,非正常退出之后,重新连接,会出现无法发送和接收的问题 #100

Open youyuanshanren opened 1 year ago

youyuanshanren commented 1 year ago

我用的最新的版本,我比较注重灾难恢复,正常通信的两个程序,强行让其崩溃,并重新启动之后,就会出现无法通信的情况。而disconnect 函数也会阻塞起来没有动静。

mutouyun commented 1 year ago

用master分支上的代码试试?

youyuanshanren commented 1 year ago

我用最新的测试过了,也用例子试验了一下,最后的结论是: ipc::channel 两个建立通信连接之后,不论那个崩溃重启,都可以重新连接成功,但是ipc::route 却不可以。 你也可以自己测试一下,就那个send_recv 例子改成 route, 很容易复现

mutouyun commented 1 year ago

ipc::route 机制有点差别,可能有bug。我有空看下咋回事

mutouyun commented 1 year ago

最近又忙起来了,可能端午我在家看看

youyuanshanren commented 1 year ago

这个库性能蛮好的。可如果用在嵌入式上,必须保持稳定或者程序重启恢复机制。另外就是,当发现连接端已经断掉之后,貌似没有通知机制。

mutouyun commented 1 year ago

是的,因为连接是假的。我打算重构的时候用一些别的方式来做,比如用一个socket做连接;或者干脆抛弃连接的概念……

mutouyun commented 1 year ago

奇怪,我测试了下是正常的 image 你的崩溃指的是不是没有办法用任何signal捕获做退出清理?这种情况下确实是不支持的。
重启恢复倒是有办法,直接执行类似sudo rm -rf /dev/shm/__IPC_SHM___*这样的语句就可以了,需要注意的是确保所有route或channel进程都不存在。

youyuanshanren commented 1 year ago

就是刻意杀死程序之后,重新启动, 然后就收发不到消息了。我在linux 虚拟机和 嵌入式设备都试验过。毕竟我们注册的signal 是不完整的。异常退出就没有清理。

mutouyun commented 1 year ago

嗯,对的,这种崩溃现在确实没办法恢复 =.=

wzhao18 commented 1 year ago

hi @mutouyun, 我想请问下怎么才能清除一个channel的cache?我遇到这种情况(非正常退出)的做法就是开一个新channel,想问问可不可以直接把原来的数据给清空。

mutouyun commented 1 year ago

可以的,通过system调用sudo rm -rf /dev/shm/__IPC_SHM___*

wzhao18 commented 1 year ago

@mutouyun 感谢!

Jiwangreal commented 1 year ago

大佬,我用的代码是:6111722 (HEAD -> master, origin/master, origin/HEAD) fix: the receiver of channel will hang after disconnect,我没有改动任何代码,但是在测试msg_que这个程序时,发现:重启./msg_que r时,在./smg_que s方有时候会出现force_push: msg_id = 50160838, remain = 6496, size = 0 force_push: k = 0, cc = 1, rem_cc = 1的问题,这个问题必须得用sudo rm -rf /dev/shm/IPCSHM*这个问题解决吗?

Jiwangreal commented 1 year ago

同样的commit id:6111722 ,还有有时候会出现:force_push: msg_id = 10457620, remain = 11104, size = 0 fail mutex lock[131] fail condition timedwait[1]: tm = 100, tv_sec = 528925, tv_nsec = 469316999 fail mutex unlock[1] 这是啥问题啊?,我感觉出错的位置:可能在: // Only the owner can unlock. if (ftx_tid(val) != tid) { return A0_MAKE_SYSERR(EPERM); }这行代码,这块逻辑出现的问题,也是不是只能通过sudo rm -rf /dev/shm/IPCSHM*这个去解决呢?没有优雅的方式吗?

mutouyun commented 1 year ago

我最近没怎么上github……要不你邮件发我微信吧,我加你聊下

NHMMing commented 4 months ago

同样的commit id:6111722 ,还有有时候会出现:force_push: msg_id = 10457620, remain = 11104, size = 0 fail mutex lock[131] fail condition timedwait[1]: tm = 100, tv_sec = 528925, tv_nsec = 469316999 fail mutex unlock[1] 这是啥问题啊?,我感觉出错的位置:可能在: // Only the owner can unlock. if (ftx_tid(val) != tid) { return A0_MAKE_SYSERR(EPERM); }这行代码,这块逻辑出现的问题,也是不是只能通过sudo rm -rf /dev/shm/IPCSHM*这个去解决呢?没有优雅的方式吗?

@mutouyun @Jiwangreal 我也遇到了同样的问题,请问有优雅的解决方法吗?

mutouyun commented 3 months ago

额,是的,主要是异常退出导致的。。根本原因有如下几个方面:

  1. 目前的机制是尽量保证不丢消息,因此存在接收端尚未读取的消息时会进行等待,故而非法退出的接收端会卡住整个队列;
  2. linux下pthread的condition在非法退出后无法恢复(这个我好像有一个ut测试这种情况);
  3. 存在原子循环锁,非法退出导致锁未释放。

如上这几个情况里,1需要对实现做重构,并定义出不同预期的接口;3需要考虑用无锁结构重构这部分原子锁代码;2我暂时没想出啥好办法解决=.=

我最近半年太忙了,而且暂时看不到头,基本没啥时间改代码。如果你有好的点子,可以帮我提提pr……

mutouyun commented 1 month ago

123