-
Notifications
You must be signed in to change notification settings - Fork 568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
多线程并发冲突导致崩溃 #1487
Comments
好奇到底是怎么复现出来这种不定时的崩溃,似乎总是在新开会话(开机,打开应用,新建窗口)的时候。 |
好像都是在切换前台窗口时崩溃,前一个窗口在收尾,新窗口在初始化,两个窗口对应两个session,每个session都有各自的_ProcessPipeThread线程,然后两个线程就可能出现并发调用,就崩了。 |
librime是不是禁止多线程不确定,隐约记得lua多线程应该是要手动改点东西 另外记得leveldb似乎是限制线程? 验证这个多线程相关的事情可以试试手工改下rime api console,加上多线程不停的创建和关闭session,中间加个模拟按键什么的之类潜在可能导致崩溃的业务,带lua和不带lua插件分别做循环多次多线程测试,或者有更好的判断 |
至少在代码层面,是不支持多线程的,完全没做保护。 |
小狼毫是前后端分离的结构,前端窗口并不持有librime,而是始终通过唯一的WeaselServer来操作librime,前后端之间标识窗口的是ipc id,在WeaselServer通过map映射到librime中的sessionid。sessionid 的本质是指针地址。WeaselServer会持有多个sessionid,而不是每个session持有_ProcessPipeThread线程。 反证法的思路是,我也有遇到崩,关掉lua插件配置使用之后一次都没有复现了。我另外写的rime.toy并不存在多线程,一样会有机会死在lua插件上,当然我那个只有一个session没有多次的创建session的操作。 所以建议还是写测试代码再看。 |
我知道ipc和session的区别,只是为了方便解释才统一说成session,但一个ipc或者client对应一个线程是没问题的。
我上面已经解释过,之所以崩溃位置在lua,是因为lua做了错误检查,主动abort了。注意,对于多线程并发操作来说,并不一定会崩溃,轻则只是数据混乱,当然,数据混乱就更难排查了。
对于lua本身的问题,我也排查了,比如Memory确实存在问题,需要在lua层主动gc才能释放,但这跟当前说的问题无关,不是同一个问题。
我已经尝试在librime中对session map进行多线程加锁,现在运行一天了,没有崩溃,之后会再观察看看。当然需要加锁的地方肯定不止这一处,只是session map更容易被并发修改。 |
@wzv5 能不能share一下,我也帮助测试崩溃情况。谢谢! |
之前懒得折腾weasel编译环境,刚刚给搞了一下,所以直接从WeaselServer下手了,处理更容易,这也是我为什么要在这里提issue而不是在librime仓库,librime本身就没考虑多线程,从librime下手难度颇高。 修改WeaselServer就容易多了,暴力加锁: 当然这仅供测试,加锁范围有点太大了,不太好。 下载这个测试: rime.dll还用原版就行。 |
谢谢,我试试是否会少崩溃 |
经过这3天的测试,应该可以确定,至少我电脑上的崩溃就是因为多线程并发冲突。之前每天都会崩溃数次,为WeaselServer加锁后,3天没有出现任何崩溃。 如果你也遇到算法服务日常崩溃,且崩溃位置在lua插件中,不妨来试试我修改后的算法服务,看看能否解决。下载地址见我之前的回复,只要替换 WeaselServer.exe 就行了。 至于如何解决多线程并发冲突,最简单的方法就是像我上面发的那样,为 HandlePipeMessage 加锁,两行代码搞定。 最后补充一下我使用的配置: 我只能说在我这套配置下,lua插件是替weasel背锅了,如果你用了其他lua脚本,请自行检查脚本有没有问题。 |
@lotem 公子抽空看看,似乎是历史代码,有没有可能是小狼毫 0.14.3 崩到 0.16.3 的主因。 |
我不懂啊。 |
@lotem 多线程在这里创建的: weasel/WeaselIPCServer/WeaselServerImpl.cpp Lines 411 to 412 in 78e20ab
|
weasel/WeaselIPCServer/WeaselServerImpl.cpp Line 430 in 78e20ab
這裏是 PipeServer::_ProcessPipeThread ;是不是應該在這個事件循環裏加鎖呢?_Receive 從 pipe 讀數據,還好;在 handler 的回調裏, _Send 向 pipe 寫數據,還會調 _Reconnect ;
|
应该对librime api的调用加锁,跟pipe本身没啥关系,读写pipe可以多线程。 |
寫入 pipe 能多線程嗎?會寫亂吧。 |
多线程读写pipe没问题的,每个线程持有各自独立的pipe,互不影响。 |
哦。改成管道了。 @fxliang 老師你怎麼看。 |
高强度码字(第1天上班),同步,多开几个Lua等使用了一天,的确没有错误发生。 |
不懂。 从一个不懂的角度我只能试了下termux下修改rime_api_console来跑下thread似乎是有较大概率会崩 已知的较多崩的场景(切换应用或新开应用),前后两个应用tsf里会调到 |
应该可以,反正就算真有什么问题也容易改回来🐶 |
那我先提交上去咯? |
还是外来的和尚会念经,大概是解决了数年来无故崩溃的疑难杂症了。 |
请相关人员关注,在这次更新后(当下在 CI 版本 Release),小狼毫,因崩溃而卡顿的现象有无解决: iDvel/rime-ice#1135 changzaicl 反馈再无崩溃 显性特征为:
日常出词慢、候选框出现慢(无 dmp 文件),和特定框架程序下的崩溃(如 Tauri),特定程序下(如部分 QT 框架)的出词慢不属于此列 |
哈哈,有这么夸张么,问题能解决就好。 |
感谢提醒,我最近在 Windows 虚拟机里测试了一下 CI 版本的小狼毫,是没有发现卡顿问题。 |
上报前请检查
操作系统信息
描述遇到的问题
发现存在多个 PipeServer::_ProcessPipeThread 线程,并发调用 librime,但 librime 并不支持多线程并发调用。
复现步骤
无,不定时出现。
用户文件
weasel_dmp.zip
压缩包内包含 dmp 文件、我修改的部分代码、我编译的 rime.dll 及其 pdb。
其他补充说明
WeaselServer 一直出现不定时崩溃,可能一天一次或多次崩溃,频率并不高。
起初怀疑是 lua 插件的问题,因为崩溃位置总是在 lua 插件中。
但在排查中发现,崩溃时 lua 环境已经乱套了,也许并不是 lua 的问题,而是来自更上层的代码。
查看 librime 代码发现,librime 并不支持多线程并发调用,于是怀疑是存在并发调用导致的崩溃。
在 librime 中加入了一些并发调用检查后,果然抓到了并发调用。
The text was updated successfully, but these errors were encountered: