按道理,运行时在运行其他用户协程时,才应该执行抢占。运行时的调度代码不应该被抢占。那么,收到抢占信号处理时,如何判定当前是谁被中断执行?
在代码中,有如下代码:
func isAsyncSafePoint(gp *g, pc, sp, lr uintptr) (bool, uintptr) {
mp := gp.m
// Only user Gs can have safe-points. We check this first
// because it's extremely common that we'll catch mp in the
// scheduler processing this G preemption.
if mp.curg != gp {
return false, 0
}
........
但是对if mp.curg != gp 判断有疑问。
比如在调度代码中有下面这样的代码:
1 mp.curg = 用户协程g
2 切换到用户协程g
在执行1之后,未执行2之前收到了抢占信号,上面的判断语句 if mp.curg != gp 失效,不会返回false, 导致调度代码被抢占。
是否这样理解?
手机输入,若格式有问题,请谅解。
如果用c实现,可以有两种方法:
1. 通过backtrace 来判断,这两者的调用栈是不一样的;
2. 设置协程和线程堆栈时,通过mmap分配堆栈内存,让它们的地址隔开,在信号不理函数中,通过上下文的rsp寄存器来判断。
#2
更多评论