Goroutine和for循环

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

Goroutine and for loop

问题

我只想做的是将一个值发送到通道,并从main()函数返回,在从通道ch接收到一个值后立即退出程序。

但是这段代码会一直运行下去:

ch := make(chan int)

for {
    go func() {
        ch <- 1
    }()
}

<-ch

我如何在从通道接收到一个值后,通过这个for循环返回呢?

为什么这段代码会一直运行下去?

Go Playground链接在这里:

http://play.golang.org/p/EvmT6Pw96Y

英文:

All I want to do is to send one value to the channel and return from the main() function and exit the program right after I receive one value from the channel ch.

But this keeps running forever:

ch := make(chan int)

for {
    go func() {
        ch &lt;- 1
    }()
}

&lt;-ch

How do I return with this for loop after I receive one value from the channel?

And why does this run forever?

Go playground link is here

http://play.golang.org/p/EvmT6Pw96Y

答案1

得分: 3

由于for循环永远运行,你的代码也会永远运行。在for循环之后接收ch的部分永远不会被执行。

如果你希望代码在某个时刻退出,你必须在某个时刻结束for循环,例如只让它运行一定数量的迭代:

for i := 0; i < 5; i++ {
    ...
}

所以如果你只运行5次迭代(就像我的例子中一样),在for循环之后接收ch的部分将会被执行,这可能会阻塞(因为ch是无缓冲的),如果其他goroutine尚未运行,至少有一个已启动的goroutine将会被执行,它会在通道上发送一个值,这可能会触发主goroutine继续执行(因为它的阻塞操作不再阻塞)。

还要注意,Go内存模型只保证某些事件在其他事件之前发生,你无法保证两个并发的goroutine如何执行。你无法保证在主goroutine在接收ch时启动的goroutine会在之前开始执行。

通常情况下,当一个goroutine被阻塞(例如阻塞的通道接收操作),运行时可能会调度另一个goroutine来运行。

英文:

Since the for loop runs forever, your code runs forever. Receiving from ch after the for loop is never reached.

If you want your code to exit sometime, you have to end the for loop sometime, e.g. make it run only a certain number of iterations:

for i := 0; i &lt; 5; i++ {
    ...
}

So if you only run 5 iterations (like in my example), after the for loop receiving from ch will be executed which may block (because ch is unbuffered) if other goroutines have not yet run, and at least one of the started goroutines will be executed which sends a value on the channel which may trigger the main goroutine to continue (because its blocking operating is no longer blocking).

Also note that the Go Memory Model only guarantees that certain events happen before other events, you have no guarantee how 2 concurrent goroutines are executed. You have no guarantee that the goroutines started in the for loop will start to execute before the main goroutine gets blocked at receiving from ch.

Usually when a goroutine gets blocked (e.g. blocking channel receive operation), the runtime may schedule another goroutine to run.

huangapple
  • 本文由 发表于 2015年4月21日 13:02:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/29763309.html
匿名

发表评论

匿名网友

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

确定