英文:
why the "infinite" for loop is not processed?
问题
我需要等待x.Addr被更新,但是似乎for循环没有运行。我怀疑这是由于Go调度器的原因,我想知道为什么会这样工作,或者是否有任何方法可以修复它(不使用通道)。
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
}
英文:
I need to wait until x.Addr is being updated but it seems the for loop is not run. I suspect this is due the go scheduler and I'm wondering why it works this way or if there is any way I can fix it(without channels).
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
}
答案1
得分: 3
你的代码有两个(三个)问题。
首先,你是对的,在循环中没有给调度器控制权,因此无法执行更新的goroutine。要解决这个问题,你可以将GOMAXPROCS
设置为大于1的值,这样多个goroutine可以并行运行。
(然而,就目前而言,这并没有帮助,因为你将x按值传递给了更新函数,这意味着主goroutine永远不会看到x的更新。要解决这个问题,你必须通过指针传递x。现在已经过时,因为OP修复了代码。)
最后,注意你在Addr
上存在数据竞争,因为你没有使用原子加载和存储。
英文:
There are two (three) problems with your code.
First, you are right that there is no point in the loop at which you give control to the scheduler and such it can't execute the update goroutine. To fix this you can set GOMAXPROCS
to something bigger than one and then multiple goroutines can run in parallel.
(However, as it is this won't help as you pass x by value to the update function which means that the main goroutine will never see the update on x. To fix this problem you have to pass x by pointer. Now obsolete as OP fixed the code.)
Finally, note that you have a data race on Addr
as you are not using atomic loads and stores.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论