【发布时间】:2018-08-03 19:51:51
【问题描述】:
接收器总是阻塞,直到有数据接收。如果通道没有缓冲,发送方会阻塞,直到接收方收到该值。
但是signal.Notify 将信号中继到无缓冲的通道而不会阻塞。这是如何工作的,是否可以与其他 chan
【问题讨论】:
接收器总是阻塞,直到有数据接收。如果通道没有缓冲,发送方会阻塞,直到接收方收到该值。
但是signal.Notify 将信号中继到无缓冲的通道而不会阻塞。这是如何工作的,是否可以与其他 chan
【问题讨论】:
【讨论】:
sync.Once。
你总是可以避免阻塞,同时(可能)仍然通过使用另一个 goroutine 来保证交付:
go func() { channel <- message }()
当然,这只是使用 goroutine 调度器作为频道的替代缓冲区,这可能是明智的,也可能不是明智的。
【讨论】:
这就是 Notify 文档明确指出您应该使用缓冲通道的原因
使用Go 1.17,the tool vet 也会更清楚:
调用信号的新警告。通知无缓冲通道
vet工具现在会警告对signal.Notify的调用,其中传入信号被发送到无缓冲通道。使用无缓冲通道可能会丢失在其上发送的信号,因为
signal.Notify在发送到通道时不会阻塞。例如:
c := make(chan os.Signal) // signals are sent on c before the channel is read from. // This signal may be dropped as c is unbuffered. signal.Notify(c, os.Interrupt)
signal.Notify的用户应使用具有足够缓冲空间的通道来跟上预期的信号速率。
【讨论】:
所以,这并不能直接解决问题,因为它要求一个无缓冲的通道,但如果你只想让它在发送时不阻塞,这就是我想出的:
ch := make(chan shared.BlogPost, 1024)
您只是输入了一个比预期大的数字。如果您事先不知道最大容量,那么此解决方案可能不适合您。
还要记住,go 会急切地分配通道,所以要小心内存使用。
【讨论】: