当我从goroutine调用C代码时,它会以任何方式影响其他goroutine的调度吗?我知道,如果在Erlang中调用NIF,它会阻塞另一个进程(Erlang),直到函数返回为止。这是戈朗的案子吗?C代码会阻塞大猩猩调度程序吗?
发布于 2015-02-06 01:06:53
从Go代码中调用C函数并不会阻止其他goroutines的运行。
它确实对调度程序有影响。运行C函数的goroutine不一定计算在GOMAXPROCS限制之外。它将开始对GOMAXPROCS进行计数,但是如果在sysmon后台goroutine运行时C函数已经阻塞了20多个,那么调度程序将被允许启动另一个goroutine,如果有一个已经准备好运行。这些细节取决于特定的Go版本,并且可能会更改。
发布于 2015-02-05 22:00:07
这是一个非常好的问题,除了在代码中,我没有找到任何官方声明。我很高兴对正式文件有任何提示。
答案是否,cgo调用不阻塞调度程序。
对于下面的内容,很好地了解到,内部Go使用G作为goroutines,M用于机器(线程),P用于proccessor。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调用goroutine锁定到OS线程)使运行时能够分配一个新的OS线程(理论上超过GOMAXPROCS)。
https://stackoverflow.com/questions/28354141
复制相似问题