2015-02-05 16 views
6

Khi tôi gọi mã C từ một goroutine, nó có ảnh hưởng đến việc lập kế hoạch của các goroutine khác theo bất kỳ cách nào không? Tôi biết rằng nếu tôi gọi một NIF trong Erlang, nó chặn các quá trình khác (Erlang), cho đến khi hàm trả về. Đây có phải là trường hợp ở Golang không? Mã C có chặn trình lên lịch goroutines không?Mã C và lập lịch trình goroutine

Trả lời

8

Gọi hàm C từ mã Go không ngăn các goroutines khác chạy.

Nó có tác dụng lên lịch biểu. Một goroutine chạy một hàm C không nhất thiết được tính vào giới hạn GOMAXPROCS. Nó sẽ bắt đầu đếm ngược với GOMAXPROCS, nhưng nếu chức năng C đã bị chặn cho hơn 20us tại thời điểm goroutine nền sysmon chạy, thì trình lên lịch sẽ được phép khởi động một goroutine khác nếu có sẵn một trình chạy. Những chi tiết này phụ thuộc vào phiên bản Go cụ thể và có thể thay đổi.

6

Đây là câu hỏi rất hay mà tôi không tìm thấy bất kỳ tuyên bố chính thức nào trên bay ngoại trừ trong mã. Tôi sẽ rất vui vì bất kỳ gợi ý nào về tài liệu chính thức.

Câu trả lời là không, cuộc gọi cgo không chặn trình lên lịch.

Đối với (chủ đề) sau đó là tốt để biết rằng trong nội bộ Go sử dụng G cho goroutines, M cho máy và P cho proccessor. Goroutines được chạy trên bộ vi xử lý chạy trên máy.

Gọi một hàm C từ G hoạt động như sau theo 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 chủ yếu kể về thời gian chạy mà goroutine này bây giờ là dưới sự kiểm soát 'bên ngoài', giống như trong các tình huống khi chúng ta làm syscalls cho hạt nhân. Một bit có thể hữu ích khác là khóa g thành m (khóa cgo gọi goroutine cho chuỗi hệ điều hành) cho phép thời gian chạy phân bổ một chuỗi hệ điều hành mới (theo lý thuyết vượt quá GOMAXPROCS).

+1

Không có tài liệu chính thức cho biết "gọi một hàm C không chặn các goroutines khác" vì đó là cách nó hoạt động tự nhiên. Nó sẽ chỉ cần thiết để tài liệu này nếu nó không hoạt động theo cách này. – iant

Các vấn đề liên quan