C code and goroutine

When I call C code from goroutine, does this affect the planning of other goroutines in any way? I know that if I call NIF in Erlang, it blocks other (Erlang) processes until the function returns. Is it in the Golang? Does goroutines scheduler block c code?

+6
source share
2 answers

Calling the C function from Go code does not prevent other goroutines from starting.

This affects the scheduler. Gorotin performing function C does not necessarily take into account the GOMAXPROCS constraint. It will start the countdown with GOMAXPROCS, but if the C function is blocked for more than 20us while the goroutine of the sysmon background is running, then the scheduler will be allowed to start another goroutine if there is one ready to run. These details vary by version of Go and are subject to change.

+8
source

This is a very good question, for which I did not find an official statement on the fly, except for the code. I would be happy for any hint of official documentation.

The answer is no, cgo calls do not block the scheduler .

For future reference, it is useful to know that inside Go uses G for goroutines, M for machines (threads) and P for proccessor. Gorut run on processors running on machines.

The function call C from G works in accordance with the 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) 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 essentially says that the runtime of this goroutine is now under "external" control, as in the situation when we do syscalls for the kernel. Another probably useful bit is that blocking g to m (blocking the call to ggooutine cgo for an OS thread) allows the runtime to allocate a new OS thread (theoretically exceeding GOMAXPROCS ).

+6
source

Source: https://habr.com/ru/post/982071/


All Articles