golang channel 封装
对于closed或nil通道,规则如下:
- 无论收发,nil通道都会阻塞。
- 不能关闭nil通道。
- 重复关闭通道,引发panic !
- 向已关闭通道发送数据,引发 panic!
- 从已关闭通道接收数据,返回缓冲数据或零值。
nil通道是指没有make的变量。鉴于通道关闭后,所有基于此的阻塞都被解除,可用作通知。
没有判断通道是否已被关闭的直接方法,只能透过收发模式获知,
操作 | 已关闭的channel | nil channel |
---|---|---|
读 | 如果channel中还有数据,可以继续读取;如果channel中没有数据了, 可以读到零值 | 永久阻塞(deadlock) |
写 | panic: send on closed channel | 永久阻塞(deadlock) |
close | panic: close of closed channel | panic: close of nil channel |
为避免重复关闭,可包装close函数。也可以类似方式封装send recv 操作。
func closechan[T any](c chan T) {
defer func(){
recover()
}()
close(c)
}
func main() {
c := make(chan int, 2)
closechan(c)
closechan(c)
}
可使用 sync.RWMutex、sync.Once 优化设计。
type Queue[T any] struct {
sync.Mutex
ch chan T
cap int
closed bool
}
func NewQueue[T any](cap int) *Queue[T] {
return &Queue[T]{
ch: make(chan T, cap),
}
}
func (q *Queue[T]) Close() {
q.Lock()
defer q.Unlock()
if !q.closed {
close(q.ch)
q.closed = true
}
}
func (q *Queue[T]) IsClosed() bool {
q.Lock()
defer q.Unlock()
return q.closed
}
// ---------------------------------
func main() {
var wg sync.WaitGroup
q := NewQueue[int](3)
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
defer q.Close()
println(q.IsClosed())
}()
}
wg.Wait()
}
利用 nil 通道阻止退出。
func main() {
<-(chan struct{})(nil) // select{}
}
http代理服务器(3-4-7层代理)-网络事件库公共组件、内核kernel驱动 摄像头驱动 tcpip网络协议栈、netfilter、bridge 好像看过!!!!
但行好事 莫问前程
--身高体重180的胖子
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
2023-05-11 gin 框架使用
2020-05-11 quic 2 ietf-transport-draft-ietf-quic-transport-09
2019-05-11 linux nf_conntrack 连接跟踪机制
2019-05-11 linux Netfilterr中扩展match target
2019-05-11 linux netfilter ----iptable_filter
2019-05-11 linux netfilter rule match target 数据结构
2019-05-11 linux netfilter 五个钩子点