go channel 应由能确定所有发送都已完成的一方关闭。只有一个生产者时由它关闭。多个生产者共享一个 channel 时,由协调协程等待全部生产者结束后关闭。
单个生产者发完再关闭
把示例保存为 main.go。消费者用 range 持续读取,直到 Channel 关闭且缓冲数据读完。
package main
import "fmt"
func main() {
jobs := make(chan int)
go func() {
defer close(jobs)
for _, value := range []int{1, 2, 3} {
jobs <p><img src="https://img.php.cn/upload/image/617/132/731/1794548459465082.jpg?x-oss-process=image/resize,p_40" alt=""></p><p>运行 go run main.go,预期输出 1、2、3,然后程序退出。</p><h2>多个生产者由协调协程统一关闭</h2><p>在另一个目录把下面的完整程序保存为 main.go。先登记生产者数量,再启动协程。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill11891" title="TG Channel Manager"><img
src="https://img.php.cn/upload/skill/001/246/273/6adaf20dbae7c507.jpg" alt="TG Channel Manager" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill11891" title="TG Channel Manager" class="overflowclass">TG Channel Manager</a>
<p class="overflowclass">通用配置驱动的内容管道引擎,支持任意 Telegram 频道:通过 SearXNG 搜索新闻、草稿、定时发布、去重。支持全部频道...</p>
</div>
<a rel="nofollow" href="/xiazai/skill11891" title="TG Channel Manager" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><pre class="brush:php;toolbar:false;">package main
import (
"fmt"
"sync"
)
func main() {
jobs := make(chan int)
var producers sync.WaitGroup
producers.Add(2)
for _, value := range []int{10, 20} {
go func(value int) {
defer producers.Done()
jobs <p>两项到达的顺序可能变化,合计应始终是 30。</p><h2>用竞态检测运行示例</h2><p>在支持 Go 竞态检测的本机环境运行。</p><pre class="brush:php;toolbar:false;">go run -race main.go
如果消费者可能提前结束,应加入取消信号,让生产者也能停止等待发送。










