当从下面的代码中删除 fmt.Print()
行时,代码将无限运行。为什么?
package main
import "fmt"
import "time"
import "sync/atomic"
func main() {
var ops uint64 = 0
for i := 0; i < 50; i++ {
go func() {
for {
atomic.AddUint64(&ops, 1)
fmt.Print()
}
}()
}
time.Sleep(time.Second)
opsFinal := atomic.LoadUint64(&ops)
fmt.Println("ops:", opsFinal)
}
最佳答案
Go By Example article includes :
// Allow other goroutines to proceed.
runtime.Gosched()
fmt.Print()
起着类似的作用,并允许 main()
有机会继续执行。
即使在无限循环的情况下,export GOMAXPROCS=2
也可能有助于程序完成,如“golang: goroute with select doesn't stop unless I added a fmt.Print()
”中所述。
fmt.Print()
explicitly passes control to some syscall stuff
是的,go1.2+ has pre-emption in the scheduler
In prior releases, a goroutine that was looping forever could starve out other goroutines on the same thread, a serious problem when
GOMAXPROCS
provided only one user thread.In Go 1.2, this is partially addressed: The scheduler is invoked occasionally upon entry to a function. This means that any loop that includes a (non-inlined) function call can be pre-empted, allowing other goroutines to run on the same thread.
请注意(我强调的)重点:在您的示例中,for 循环 atomic.AddUint64(&ops, 1)
可能是内联的。那里没有先发制人。
2017 年更新:Go 1.10 will get rid of GOMAXPROCS
.
关于戈朗 : goroutine infinite-loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25073815/