go - 在选择中支持一种通信(chan)
问题描述
我知道,如果有多个“通信”可以在select
声明中进行,则随机选择一个。我正在尝试找到一种替代方法,它可以更喜欢一种“交流”而不是另一种。
背景是我正在使用上下文杀死的通道上的 go-routine 中发送值。当我杀死它时,我希望立即关闭通道,但目前代码有时会在关闭之前在通道上发送最终值。
这是代码的简化版本:
ctx, cancel := context.WithCancel(context.Background())
ch := make(chan int)
go func() {
defer close(ch)
for i := 1; ; i++ {
select {
case <-ctx.Done():
return
case ch <- i:
}
}
}()
print(<-ch)
print(<-ch)
cancel()
print(<-ch)
print(<-ch)
这有时会打印 1200,但通常会打印 1230。 在操场上尝试一下
关于如何重组代码以支持第一种情况有什么想法吗?(即让它总是打印 1200。)
解决方案
这似乎是不可能的,因为cancel()
它不是主 goroutine 中的阻塞操作。正因为如此,当select
解除阻塞时,可能会有多种情况可用,并且没有办法让一个渠道优于另一个渠道。任何类型的 check-channel-then-write 方案都将是活泼的,因为在检查后可以取消上下文。
使用done
通道并写入它而不是上下文取消将起作用,因为写入done
通道将是主 goroutine 的阻塞操作,并且 select 将始终有一个活动案例。
推荐阅读
- mongodb - mongodb按分组字段聚合排序
- ios - 由 userNotificationCenter 而非 Firebase 函数处理的 Firebase 通知
- node.js - Node.js 异步写入串行端口
- javascript - 如何解决 TypeError: angular.element(...).scope(...).selectFileForUpload is not a function
- java - ORA-02049: 超时: 分布式事务在多线程环境中等待锁定
- windows - 批处理程序在第五个斜线后删除 txt 中的所有内容
- python - pyuno 在 libreoffice 中缺少符号并且无法使用 python2
- html - WebAPP Quiz html - 从谷歌电子表格中读取数据 - 选择工作表
- c++ - 关联容器的下界复杂度:成员函数与非成员函数
- python - 在蛇形教程环境中导入 matplotlib 错误