gpt4 book ai didi

Go调度器和CGO : Please explain this difference of behavior?

转载 作者:IT王子 更新时间:2023-10-29 02:30:10 25 4
gpt4 key购买 nike

我想知道实现原因:

package main

func main() {
c := make(chan struct{})

go func() {
print("a")
for {
}
}()

go func() {
print("b")
for {
}
}()

go func() {
print("c")
c <- struct{}{}
for {
}
}()

<-c
}

❯❯❯ GOMAXPROCS=2 go run sample1.go
ab <--- blocks.

package main

// static void loop() { for(;;); }
import "C"

func main() {
c := make(chan struct{})

go func() {
print("a")
C.loop()
print("x")
}()

go func() {
print("b")
C.loop()
print("y")
}()

go func() {
print("c")
c <- struct{}{}
C.loop()
print("z")
}()

<-c
}

❯❯❯ GOMAXPROCS=2 go run sample2.go
abc <--- ends gracefully.

更具体地说,我指的是在 go 例程调度的上下文中,C 紧密循环与 Go 紧密循环有何不同。即使 C 紧密循环应该在 Go 程序结束时突然终止,我想知道依靠这种行为来启动 C 任务而不阻塞 Go 程序是否安全。

最佳答案

运行时无法抢占真正的繁忙循环。没有调度点的 CPU 密集型循环必须在它自己的线程中,其他 goroutine 才能运行。函数调用和 channel 发送或接收操作都会产生。网络IO是异步调度的,文件IO有自己的线程。

一般设置 GOMAXPROCS > 1 就足够了,但是由于你有 3 个这样的循环,而且只有 2 个线程,调度器仍然被阻塞。如果您有一个有效的 CPU 密集型循环,这使得调度 goroutine 变得困难,您可以定期调用 runtime.GoSched() 以屈服于调度程序。在现实世界中,这通常唯一重要的地方是出现空循环的编程错误。

所有 cgo 调用都发生在 go 运行时之外的它们自己的线程中,因此这些循环对主循环没有影响,除了浪费 CPU。

关于Go调度器和CGO : Please explain this difference of behavior?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28835758/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com