英文:
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 <- 1
}()
}
<-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
答案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 < 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论