2 回答
TA贡献1864条经验 获得超2个赞
简短的回答:
对于任何通道(缓冲或不缓冲),如果没有任何内容写入通道,则通道读取块。
对于非缓冲通道,如果没有人在听,通道写入将阻塞。
这是错误通道的常用技术(因为只有一个项目会写入通道),使其成为大小为 1 的缓冲通道。它确保写入不会阻塞 - 并且 writer goroutine 可以继续其方式和返回。
因此,服务不依赖从错误通道读取的客户端调用者来执行其清理。
注意:要回收一个通道重新 GC,它只需要超出范围 - 它不需要完全耗尽。也不需要关闭。一旦它从两端超出范围,它将被 GC'ed。
TA贡献1111条经验 获得超0个赞
如果您参考 的代码ListenAndServe(),您会注意到以下关于其工作原理的注释。从那里引用本身:
// ListenAndServe 总是返回一个非零错误。在 Shutdown 或 Close 之后,
// 返回的错误是 ErrServerClosed。
还,
// 当调用 Shutdown 时,Serve、ListenAndServe 和
// ListenAndServeTLS 立即返回 ErrServerClosed。确保
// 程序没有退出,而是等待 Shutdown 返回。
Shutdown考虑到您正在优雅地处理服务器的关闭并且不让 goroutine 在优雅关闭之前退出,您的 select 块正在等待(错误)。
在func (srv *Server) Close() (例如,大多数使用defer srv.Close(),对吗?)的情况下:
// Close 立即关闭所有活动的 net.Listener 和任何
// 处于 StateNew、StateActive 或 StateIdle 状态的连接。为一个
// 关闭返回关闭服务器的
// 底层监听器返回的任何错误。
// 优雅关机,使用 Shutdown。
因此,与上述相同的解释是使用 select 块。
现在,让我们将通道分类为buffered和unbuffered,如果我们确实关心信号传递的保证(与通道的通信),那么无缓冲的可以确保它。然而,如果在您的情况下缓冲通道(大小 = 1),那么它可以确保交付但可能会延迟。
让我们详细说明unbuffered channels:
A send operation on an unbuffered channel blocks the sending goroutine until another
goroutine executes a corresponding receive on that same channel, at which point the value
is transmitted and both goroutines may continue
Conversely, if received on the channel earlier (<-chan) than send operation, then the
receiving goroutine is blocked until the corresponding send operation occurs on the
same channel on another goroutine.
上述无缓冲通道的点表示同步性质。
记住,func main()也是一个goroutine。
让我们详细说明buffered channels:
A send operation on a buffered channel pushes an element at the back of the queue,
and a receive operation pops an element from the front of the queue.
1. If the channel is full, the send operation blocks its goroutine until space is made available by another goroutine's receive.
2. If the channel is empty, a receive operation blocks until a value is sent by another goroutine.
因此,在您的情况下,通道的大小为 1。另一个发送者 goroutine 可以以非阻塞方式发送,因为另一个 goroutine 的接收者通道在收到后立即将其出列。但是,如果你还记得,我提到了大小为 1的通道的延迟交付,因为我们不知道接收器通道 goroutine 返回需要多少时间。
因此,使用阻塞发送者 goroutine select block。从引用代码的文档中,您可以看到
// 确保程序不会退出,而是等待 Shutdown 返回。
另外,为了更清楚,您可以参考:通道 的行为作者非常清楚地解释了它。
- 2 回答
- 0 关注
- 106 浏览
添加回答
举报