为了账号安全,请及时绑定邮箱和手机立即绑定

C 代码和 goroutine 调度

C 代码和 goroutine 调度

Go
九州编程 2021-09-13 15:39:26
当我从 goroutine 调用 C 代码时,它是否会以任何方式影响其他 goroutine 的调度?我知道如果我在 Erlang 中调用 NIF,它会阻塞其他(Erlang)进程,直到函数返回。在 Golang 中是这样吗?C 代码会阻塞 goroutines 调度程序吗?
查看完整描述

2 回答

?
呼如林

TA贡献1798条经验 获得超3个赞

从 Go 代码调用 C 函数不会阻止其他 goroutine 运行。

它确实对调度程序有影响。运行 C 函数的 goroutine 不一定要计入GOMAXPROCS限制。它将开始计算 GOMAXPROCS,但是如果 C 函数在 sysmon 后台 goroutine 运行时阻塞了超过 20us,那么如果有一个准备运行的 goroutine,调度程序将被允许启动另一个 goroutine。这些细节取决于特定的 Go 版本,可能会发生变化。


查看完整回答
反对 回复 2021-09-13
?
临摹微笑

TA贡献1982条经验 获得超2个赞

这是一个非常好的问题,除了代码之外,我没有立即找到任何官方声明。我很高兴对官方文档有任何提示。


答案是否定的, 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)。


查看完整回答
反对 回复 2021-09-13
  • 2 回答
  • 0 关注
  • 225 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信