Ble*_*ers 3 multithreading atomic go
通过示例Go:原子计数器.代码示例在调用runtime.Gosched后调用atomic.AddUint64.
atomic.AddUint64 被召唤
不幸的是,我发现解释并不那么内容和令人满意.
我尝试运行示例代码(为简明起见删除了注释):
package main
import "fmt"
import "time"
import "sync/atomic"
import "runtime"
func main() {
var ops uint64 = 0
for i := 0; i < 50; i++ {
go func() {
for {
atomic.AddUint64(&ops, 1)
runtime.Gosched()
}
}()
}
time.Sleep(time.Second)
opsFinal := atomic.LoadUint64(&ops)
fmt.Println("ops:", opsFinal)
}
Run Code Online (Sandbox Code Playgroud)
没有runtime.Gosched()(go run conc.go)和程序永远不会退出,即使我将循环从50减少到1.
题:
在呼叫之后发生什么事情atomic.AddUint64有必要打电话runtime.Gosched?这是怎么runtime.Gosched解决的?我在sync/atomic文档中没有找到任何暗示这样的东西.
这就是合作多线程的工作原理.如果一个线程仍然准备好运行,它将继续运行而其他线程则不会运行.显式和隐式抢占点用于允许其他线程运行.如果你的线程有一个循环,它在没有隐式抢占点的情况下会保持很长时间,那么如果你没有添加一个明确的抢占点,你就会饿死其他线程.
这个答案提供了有关Go何时使用协作多线程的更多信息.