go - 在生成 goroutine 的函数返回之后,发送到没有接收器的无缓冲 channel 的 goroutine 是否会永远阻塞?

标签 go

请考虑以下处理程序,

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将回调作为参数。在这个回调中(这可能永远不会发生)
我向确认 channel 发送一个 bool 值。如果 1 秒后未确认,则超时。

我正在尝试实现超时的方法。我写了这个 goroutine 并且它有效。
然而,根据 this playground goroutine 在生成它的函数返回后继续运行。

所以我认为因为 goroutine 一直在运行并试图将值发送到没有接收器的无缓冲 channel ,所以 goroutine 将永远阻塞。我想我可以通过使用 1 的缓冲区大小来解决这个问题。

我想知道我的假设是否正确。如果是这样,有没有比使用缓冲区大小为 1 并让它静默完成更好的方法来阻止它?

最佳答案

在您的场景中,goroutine 将泄漏(它将继续存在)。如果没有人在收听该 channel ,则终止 goroutine 的正确方法是使用非阻塞写入:

 go func() {
            time.Sleep(time.Second)
            select {
               case ack <- false:
               default:
            }
        }()

这样,如果超时后没有人在听,它将选择 default , 并终止 goroutine。

关于go - 在生成 goroutine 的函数返回之后,发送到没有接收器的无缓冲 channel 的 goroutine 是否会永远阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59275255/

相关文章:

amazon-web-services - 在 AWS SDK (golang) 中设置内容处置和内容类型无效

戈朗 : Preferred way to tag a struct with aribtrary data

string - 为什么不使用 %v 来打印 int 和 string

go - Golang中多接口(interface)转换的简洁方式?

sql - db.Exec()未在golang中为SQL Server返回正确的RowsAffected()值

mongodb - Go Mongo Driver 检索无模式文档

ssh - 将公钥编码为 OpenSSH 格式以供显示

database - 是否应该为每个请求创建一个新的 Cloud Spanner Client 实例?

JSON 键可以是字符串或对象

go - 数据无法保存在我的数据库中