英文:
Can unbuffered channel be used to receive signal?
问题
在下面的代码中:
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-sigs
fmt.Println()
fmt.Println(sig)
done <- true
}()
fmt.Println("awaiting signal")
<-done
fmt.Println("exiting")
}
在接收信号的地方使用了一个大小为1的缓冲通道。
无缓冲通道提供了交付的保证。
大小为1的缓冲通道提供了延迟的保证。
在这种情况下,我们可以使用无缓冲通道吗? sigs := make(chan os.signal)
英文:
In the below code:
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-sigs
fmt.Println()
fmt.Println(sig)
done <- true
}()
fmt.Println("awaiting signal")
<-done
fmt.Println("exiting")
}
Size one buffered channel is used for receiving signal.
Unbuffered channels provide guarantee of delivery.
Size one buffered channel provides delayed guarantee
Can we use unbuffered channel in this scenario? sigs := make(chan os.Signal)
答案1
得分: 15
从signal.Notify文档中可以得知:
> signal包不会阻塞对c的发送操作:调用者必须确保c具有足够的缓冲空间以跟上预期的信号速率。对于仅用于通知一个信号值的通道,大小为1的缓冲区足够。
所以,回答你的问题:
> 无缓冲通道提供交付的保证。
这是不正确的。只有在你了解发送方和接收方的行为时,才能保证交付。
在这种情况下,发送方是非阻塞的。因此,如果接收方没有等待信号,消息将被丢弃。
> 大小为1的缓冲通道提供延迟保证。
通道中没有“延迟”。缓冲区只是指通道中可以存储的项目数量。
> 在这种情况下,我们可以使用无缓冲通道吗?
代码可能会工作,但不能保证。问题在于你不知道这行代码何时会被执行:
sig := <-sigs
在signal.Notify
之后但在<-sigs
之前到达的任何信号都将被丢弃(如果通道是无缓冲的)。请记住,signal.Notify
是非阻塞的,这意味着它会放弃等待。
如果你不希望信号被丢弃,请使用带缓冲的通道。
这种情况不太可能发生,但从技术上讲是可能的。
英文:
From the signal.Notify documentation
> Package signal will not block sending to c: the caller must ensure that c has sufficient buffer space to keep up with the expected signal rate. For a channel used for notification of just one signal value, a buffer of size 1 is sufficient.
So, to answer your question:
> Unbuffered channels provide guarantee of delivery.
This is incorrect. Delivery can only be guaranteed if you know both the behavior of the sender and receiver.
In this case, the sender is non-blocking. So if the receiver is not waiting for a signal, the message will be discarded.
> Size one buffered channel provides delayed guarantee
There is no “delay” in a channel. The buffer is just how many items can be stored in the channel.
> Can we use unbuffered channel in this scenario?
The code will probably work, but it is not guaranteed to work. The problem is that you don’t know when this line will get executed:
sig := <-sigs
Any signal which arrives after signal.Notify
but before <-sigs
will get discarded (if the channel is unbuffered). Remember that signal.Notify
is non-blocking—this just means that it will give up instead of wait.
If you don’t want signals to get discarded, use a buffered channel.
This scenario is unlikely, sure. But it is technically possible.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论