sylar
sylar copied to clipboard
可能的bug
发现两个可能的bug,都是与多线程安全有关
- IOManager 模块中,定时器的调度可能使其他线程误以为没有任务而stopping终止。
- 对于协程调度中,在添加事件监听后,YieldHold协程之前,如果由于事件触发,导致该协程被加入调度,并被其他线程调度了,此时同一协程被两个线程同时调度而发生异常。
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(); } }
1.我没有碰到过,描述的不够详细 2.这个问题不存在 if(it->fiber && it->fiber->getState() == Fiber::EXEC) { ++it; continue; } 如果协程在运行将会被跳过
1.我没有碰到过,描述的不够详细 2.这个问题不存在 if(it->fiber && it->fiber->getState() == Fiber::EXEC) { ++it; continue; } 如果协程在运行将会被跳过 如果只是这样修改还是会出问题,现版本作者修改了协程置HOLD状态部分代码,注销了协程内HOLD状态设置,才回避了这个问题,但我感觉这么改有些破坏了协程模块的封装性。
协程模块本来就不够独立,状态都是由调度器改变的,如果想让协程模块单独使用,还是建议修改协程的实现
问题1 超时回调中 对io的操作是线程安全的 不存在丢|漏事件 问题2类似的 https://github.com/sylar-yin/sylar/issues/13 源码调度器 在fiber被调度后重置为HOLD态 无可厚非
在Timer中使用shared_ptr作为set的键,可能存在每次超时函数中将所有未超时的定时器都取出并调度。