go - 这是在 golang 中终止 goroutine 的正确方法吗?

标签 go

我正在构建一个需要启动自己的 HTTP 服务器的命令行应用程序。 我的想法是在我的主程序中的 goroutine 中启动 http 服务器,如下所示:

func main() {
    go myserver()

    // perform lots of time-consuming tasks
}

func myserver() {
    s := &http.Server{
        Addr: ":8080",
        Handler: MyHandler{},
    }
    log.Fatal(s.ListenAndServe())
}
  1. 我的主要功能需要能够告诉 goroutine 结束。由于网络服务器阻塞了 ListenAndServe 方法,因此无法通过 sync.WaitGroup 或 channel 发送信号。
  2. 我的一个想法是向网络服务器发送 HTTP POST,并要求它在收到特定的商定值后自杀。

还有其他 golang 惯用的替代方法吗?

最佳答案

如果您在程序退出之前一直在运行 Web 界面,您可以直接从主线程返回。即使另一个 goroutine 正在工作,从主线程返回也会退出程序。如果想让主线程向http服务器发送kill,最好的办法就是关闭监听器。

func main() {
    l, err := net.Listen("tcp", ":8080")
    if err != nil {
        log.Fatal(err)
    }
    go myserver(l)

    // perform lots of time-consuming tasks

    l.Close()
}

func myserver(l net.Listener) {
    s := &http.Server{
        Addr:    ":8080",
        Handler: MyHandler{},
    }
    log.Print(s.Serve(l))
}

这不会关闭已经打开的连接。它只会阻止创建新的。您需要向您的处理程序添加逻辑和/或停止保持事件状态,以确保在您杀死监听器后连接不会长时间重复使用。

关于go - 这是在 golang 中终止 goroutine 的正确方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22138588/

相关文章:

go - 日期格式显示错误的日期

go - 如何更新多对多关系

Golang 获取带有 httptest 失败的错误消息

go - drone.io 不使用 GitHub repo 的 .drone.yml 文件

unit-testing - 导出 Golang 包进行测试?

go - 同时读取文件

go - 使用一个签名 key 对jwt进行签名安全吗?

sql - 如何使用包 database/sql 批处理 sql 语句

go - 这个成语有名字吗?

http - Beego 从 HTTP 切换到 HTTPS