[英]does a goroutine sending to an unbuffered channel without receivers block forever, after the function that spawns the goroutine returns?
请考虑以下处理程序,
http.HandleFunc("/task", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", *cors)
if r.Method != http.MethodPost {
http.Error(w, "only POST method is allowed", http.StatusMethodNotAllowed)
return
}
ack := make(chan bool)
go func() {
time.Sleep(time.Second)
ack <- false
}()
server.BroadcastToRoom(r.FormValue("alias"), "task", task{TaskID: "1"}, func() {
ack <- true
})
if a := <-ack; !a {
w.WriteHeader(http.StatusNoContent)
} else {
w.WriteHeader(http.StatusCreated)
}
})
BroadcastToRoom
将回调作为参数。 在这个回调中(可能永远不会发生),我向确认通道发送了一个布尔值。 如果 1 秒后未确认,则超时。
我正在试验实现超时的方法。 我写了这个 goroutine 并且它有效。 但是,根据这个操场,goroutine 在产生它的函数返回后继续运行。
所以我认为因为 goroutine 一直在运行并试图将一个值发送到一个没有接收器的无缓冲通道,goroutine 将永远阻塞。 我想我可以通过使用大小为 1 的缓冲区来解决这个问题。
我想知道我的假设是否正确。 如果是这样,是否有比使用缓冲区大小为 1 并让它静默完成更好的方法来阻止它?
在您的场景中,goroutine 将泄漏(它将继续存在)。 如果没有人在侦听该通道,则终止 goroutine 的正确方法是使用非阻塞写入:
go func() {
time.Sleep(time.Second)
select {
case ack <- false:
default:
}
}()
这样,如果超时后没有人在侦听,它将选择default
,并终止 goroutine。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.