当前go版本1.16.2, os: Linux
初始化initsig
// sigPreempt是一个用于非协作抢占的信号
const sigPreempt = _SIGURG
func initsig(preinit bool) {
for i := uint32(0); i < _NSIG; i++ {
fwdSig[i] = getsig(i)
,,,
setsig(i, funcPC(sighandler)) // 注册信号对应的回调方法
}
}
func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
,,,
if sig == sigPreempt { // 如果是抢占信号
// Might be a preemption signal.
doSigPreempt(gp, c)
}
,,,
}
// 执行抢占
func doSigPreempt(gp *g, ctxt *sigctxt) {
if wantAsyncPreempt(gp) {
// isAsyncSafePoint主要检测函数是否是用户函数还是系统函数,gp是否是非g0, sp栈有空余等
if ok, newpc := isAsyncSafePoint(gp, ctxt.sigpc(), ctxt.sigsp(), ctxt.siglr()); ok {
// Adjust the PC and inject a call to asyncPreempt.
ctxt.pushCall(funcPC(asyncPreempt), newpc)
}
}
// Acknowledge the preemption.
atomic.Xadd(&gp.m.preemptGen, 1)
atomic.Store(&gp.m.signalPending, 0)
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。