2015-02-05 43 views
6

當我從goroutine調用C代碼時,它會以任何方式影響其他goroutines的調度嗎?我知道如果我在Erlang中調用NIF,它會阻塞其他(Erlang)進程,直到函數返回。 Golang的情況如何? C代碼是否阻塞了goroutines調度程序?C代碼和goroutine調度

回答

8

從Go代碼調用C函數並不妨礙其他的goroutines運行。

它對調度程序有影響。運行C函數的goroutine不一定要計入GOMAXPROCS的限制。它將從GOMAXPROCS開始計數,但如果C函數在sysmon後臺goroutine運行時阻塞超過20us,那麼如果有一個準備運行,調度程序將被允許啓動另一個goroutine。這些細節取決於具體的Go版本,並且可能會發生變化。

6

這是一個非常好的問題,我除了在代碼中沒有發現任何官方聲明。我會很高興任何提示官方文件。

答案是不,cgo調用不會阻止調度程序

對於以下這是很好的知道,內部Go使用的夠程,中號對機器(線程)和P爲proccessor。 Goroutines運行在機器上運行的處理器上。

調用C函數給G作品根據code documentation如下:

// 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主要用來告訴運行時,這個夠程,現在是在「外部」控制,就像我們做的系統調用的情況到內核​​。另一個可能有用的位是鎖定gm(將cgo調用goroutine鎖定到OS線程)使運行時能夠分配新的OS線程(理論上超過GOMAXPROCS)。

+1

沒有官方文檔說「調用C函數不會阻塞其他goroutines」,因爲這是它自然應該工作的方式。如果它不以這種方式工作,那麼只需要證明這一點。 – iant 2015-02-06 01:08:11