这是Golang的示例代码之一。但是无法理解为什么在这种情况下需要“完成”渠道。
https://gobyexample.com/closing-channels
没有理由将真实消息发送到已完成的频道。当打印“已发送所有作业”消息时,我们可以知道作业通道已完成,不是吗?
我删除了相对于已完成频道的代码,结果仍然相同。
TL;DR:有一个竞争条件---你很幸运。
如果您没有done通道,则程序的输出是不确定的。
根据线程的执行顺序,主线程可能会在 goroutine 完成处理之前退出,从而导致 goroutine 在中途被杀死。
通过强制主线程从done通道读取,我们强制主线程等待,直到done通道中有一些数据要消耗。这为我们提供了一个简洁的同步机制,其中 goroutine 通知主线程它是通过写入done通道来完成的。这反过来导致主线程的阻塞<- done完成并导致程序终止。
小智 5
没有结果是不一样的:在许多情况下(例如,不同的CPU负载,并且不确定性和系统相关的行为),
您的主goroutine会在goroutine之前退出received job,因此,您无法保证all jobs received,例如Add
time.Sleep(500)
Run Code Online (Sandbox Code Playgroud)
之前
fmt.Println("received job", j)
Run Code Online (Sandbox Code Playgroud)
要查看此内容,请在The Go Playground上尝试:
// _Closing_ a channel indicates that no more values
// will be sent on it. This can be useful to communicate
// completion to the channel's receivers.
package main
import (
"fmt"
"time"
)
// In this example we'll use a `jobs` channel to
// communicate work to be done from the `main()` goroutine
// to a worker goroutine. When we have no more jobs for
// the worker we'll `close` the `jobs` channel.
func main() {
jobs := make(chan int, 5)
//done := make(chan bool)
// Here's the worker goroutine. It repeatedly receives
// from `jobs` with `j, more := <-jobs`. In this
// special 2-value form of receive, the `more` value
// will be `false` if `jobs` has been `close`d and all
// values in the channel have already been received.
// We use this to notify on `done` when we've worked
// all our jobs.
go func() {
for {
j, more := <-jobs
if more {
time.Sleep(500)
fmt.Println("received job", j)
} else {
fmt.Println("received all jobs")
//done <- true
return
}
}
}()
// This sends 3 jobs to the worker over the `jobs`
// channel, then closes it.
for j := 1; j <= 3; j++ {
jobs <- j
fmt.Println("sent job", j)
}
close(jobs)
fmt.Println("sent all jobs")
// We await the worker using the
// [synchronization](channel-synchronization) approach
// we saw earlier.
//<-done
}
Run Code Online (Sandbox Code Playgroud)
输出:
sent job 1
sent job 2
sent job 3
sent all jobs
Run Code Online (Sandbox Code Playgroud)
代替:
sent job 1
received job 1
received job 2
sent job 2
sent job 3
received job 3
received all jobs
sent all jobs
Run Code Online (Sandbox Code Playgroud)
请参阅:
如果time.sleep包括在内,Goroutine将不执行
为什么要运行某些goroutine需要time.sleep ?
go中奇怪的频道行为
| 归档时间: |
|
| 查看次数: |
3635 次 |
| 最近记录: |