当前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)
}

xxx小M
30 声望11 粉丝

暂时放一些读书笔记, 很多内容没有整理好