为什么“无限”循环不被执行?

huangapple go评论66阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2015年7月2日 16:37:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/31179523.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定