sylar icon indicating copy to clipboard operation
sylar copied to clipboard

可能的bug

Open Lianlii opened this issue 2 years ago • 6 comments

发现两个可能的bug,都是与多线程安全有关

  1. IOManager 模块中,定时器的调度可能使其他线程误以为没有任务而stopping终止。
  2. 对于协程调度中,在添加事件监听后,YieldHold协程之前,如果由于事件触发,导致该协程被加入调度,并被其他线程调度了,此时同一协程被两个线程同时调度而发生异常。

Lianlii avatar Apr 05 '22 15:04 Lianlii

2.对于协程调度中,在添加事件监听后,YieldHold协程之前,如果由于事件触发,导致该协程被加入调度,并被其他线程调度了,此时同一协程被两个线程同时调度而发生异常。

此bug我也发现了。我的方案是在schedule::scheduleNoLock()模板函数中加个if检测是否是本协程schedule自己,即【if ( task.fiber == Fiber::GetThis())】。如果是则强制设置task的thread_id也为当前thread,即【task.threadId =GetThreadId()】。这样就避免了同一时刻有两个不同的线程竞争一个协程。

增加的代码为: if (task.fiber) { if (task.fiber == Fiber::GetThis() && thread == -1) { task.threadId = ::sylar::GetThreadId(); } }

taochaoyang avatar Apr 17 '22 08:04 taochaoyang

1.我没有碰到过,描述的不够详细 2.这个问题不存在 if(it->fiber && it->fiber->getState() == Fiber::EXEC) { ++it; continue; } 如果协程在运行将会被跳过

4kangjc avatar Apr 22 '22 01:04 4kangjc

1.我没有碰到过,描述的不够详细 2.这个问题不存在 if(it->fiber && it->fiber->getState() == Fiber::EXEC) { ++it; continue; } 如果协程在运行将会被跳过 如果只是这样修改还是会出问题,现版本作者修改了协程置HOLD状态部分代码,注销了协程内HOLD状态设置,才回避了这个问题,但我感觉这么改有些破坏了协程模块的封装性。

Lianlii avatar Apr 22 '22 02:04 Lianlii

协程模块本来就不够独立,状态都是由调度器改变的,如果想让协程模块单独使用,还是建议修改协程的实现

4kangjc avatar Apr 22 '22 04:04 4kangjc

问题1 超时回调中 对io的操作是线程安全的 不存在丢|漏事件 问题2类似的 https://github.com/sylar-yin/sylar/issues/13 源码调度器 在fiber被调度后重置为HOLD态 无可厚非

hankai17 avatar Aug 24 '22 02:08 hankai17

在Timer中使用shared_ptr作为set的键,可能存在每次超时函数中将所有未超时的定时器都取出并调度。

hps2002 avatar Oct 18 '23 06:10 hps2002