临摹微笑
这是一个非常好的问题,除了代码之外,我没有立即找到任何官方声明。我很高兴对官方文档有任何提示。答案是否定的, cgo 调用不会阻塞调度程序。对于以下内容,很高兴知道 Go 在内部使用G表示 goroutine,M表示机器(线程),P表示处理器。Goroutines 在机器上运行的处理器上运行。根据代码文档,从 G 调用 C 函数的工作方式如下:// To call into the C function f from Go, the cgo-generated code calls// runtime.cgocall(_cgo_Cfunc_f, frame), where _cgo_Cfunc_f is a// gcc-compiled function written by cgo.//// runtime.cgocall (below) locks g to m, calls entersyscall// so as not to block other goroutines or the garbage collector,// and then calls runtime.asmcgocall(_cgo_Cfunc_f, frame).//// runtime.asmcgocall (in asm_$GOARCH.s) switches to the m->g0 stack// (assumed to be an operating system-allocated stack, so safe to run// gcc-compiled code on) and calls _cgo_Cfunc_f(frame).//// _cgo_Cfunc_f invokes the actual C function f with arguments// taken from the frame structure, records the results in the frame,// and returns to runtime.asmcgocall.//// After it regains control, runtime.asmcgocall switches back to the// original g (m->curg)'s stack and returns to runtime.cgocall.//// After it regains control, runtime.cgocall calls exitsyscall, which blocks// until this m can run Go code without violating the $GOMAXPROCS limit,// and then unlocks g from m.entersyscall本质上是告诉运行时这个 goroutine 现在处于“外部”控制之下,就像我们对内核进行系统调用的情况一样。另一种可能是有用的一点是,锁定g到m(锁定CGO调用够程到操作系统的线程),运行时分配一个新的OS线程(理论上超过GOMAXPROCS)。