Go 为什么会有";“无限”;for循环未被处理?
我需要等到x.Addr被更新,但是for循环似乎没有运行。我怀疑这是由于go调度程序造成的,我想知道为什么它会这样工作,或者是否有任何方法可以修复它(没有通道) 您的代码有两(三)个问题 首先,您是对的,在循环中没有一点是您将控制权交给调度程序的,因此它不能执行更新goroutine。要解决此问题,可以将Go 为什么会有";“无限”;for循环未被处理?,go,Go,我需要等到x.Addr被更新,但是for循环似乎没有运行。我怀疑这是由于go调度程序造成的,我想知道为什么它会这样工作,或者是否有任何方法可以修复它(没有通道) 您的代码有两(三)个问题 首先,您是对的,在循环中没有一点是您将控制权交给调度程序的,因此它不能执行更新goroutine。要解决此问题,可以将GOMAXPROCS设置为大于1的值,然后多个goroutine可以并行运行 (然而,实际上这并没有帮助,因为您将x按值传递给update函数,这意味着主goroutine将永远看不到x上的更新
GOMAXPROCS
设置为大于1的值,然后多个goroutine可以并行运行
(然而,实际上这并没有帮助,因为您将x按值传递给update函数,这意味着主goroutine将永远看不到x上的更新。要解决此问题,您必须按指针传递x。由于OP修复了代码,现在已过时。)
最后,请注意,
Addr
上存在数据竞争,因为您没有使用原子加载和存储。循环的“无限”数量是否取决于GOMAXPROCS值?e、 g.如果GOMAXPROCS==3,那么我们可以使用2个无限循环?@AnthonyHunt GOMAXPROCS确定并发执行用户级代码的操作系统线程数。是的,你可以有两个无限循环。然而,您不应该依赖于这些,而应该以一种不需要这种技巧的方式来设计代码。
package main
import "fmt"
import "time"
type T struct {
Addr *string
}
func main() {
x := &T{}
go update(x)
for x.Addr == nil {
if x.Addr != nil {
break
}
}
fmt.Println("Hello, playground")
}
func update(x *T) {
time.Sleep(2 * time.Second)
y := ""
x.Addr = &y
}