我有一个运行几分钟的功能,我正在试图找到一种使用通道停止它的方法.

我想我不能像在下面的代码中那样做,因为我认为select只有在default完成之后才会处理stop的情况.

package main

import (
    "fmt"
    "time"
)

func main() {
    stop := make(chan int)

    go func() {
        for {
            select {
            case <-stop:
                fmt.Println("return")
                return
            default:
                fmt.Println("block")
                time.Sleep(5 * time.Second) // simulate a long running function
                fmt.Println("unblock")
            }
        }
    }()

    time.Sleep(1 * time.Second)
    stop <- 1
}

推荐答案

我认为你做不到:Go中的goroutines在某种意义上是合作的:除非goroutine actively试图以某种方式确定它是否应该退出,否则没有办法让它退出.

我想说这实际上是一个功能,因为如果你可以强行获取一个长期运行的Goroutine,你将无法确保它干净地退出,也就是说,正确地释放它获得的所有资源.

So either live with this (say, if your process wants to exit, just wait on that goroutine to finish) or restructure it so that it periodically checks whether it is signaled to quit. Or even consider offloading the task it performs to an external process (but note that while it's safe to kill a process with regard to releasing the resources it acquired from the OS, it's not safe with regard to external data that process might have been updating — such as files).

Go相关问答推荐

Go 1.22 http mux:在同一路径上提供一个手柄和一个FS

Kafka消费者在需要时不会暂停

如何在使用中介资源时处理函数中的`defer`

map 中的多个函数类型,Golang

在Mac中使用uname获取处理器体系 struct 时,在为AMD64构建Go二进制时出现错误结果

如何在Golang中获取mp3文件的持续时间?

Go SQLCMD比Windows本机版本慢吗?

如果values.yaml文件中不存在某个属性,如何返回默认的FALSE?

在 GoLang 中对自定义 struct 体数组进行排序

使用Cookie身份验证的Gorilla Golang Websocket优化

linter 警告:返回值被忽略

Opensearch 错误 ping 弹性服务器:由未知权威签署的 x509 证书

Golang - POST 失败(NoSurf CSRF)

如何将 base64 编码的公钥转换为 crypto.PublicKey 或 ecdsa.PublicKey

拆分文本并按空格获取字符串数组,如果文本长度超过 500,则获取字符串数组

Golang模板无法访问embedFS中的文件

在 Raspberry Pi4 上下载 Go Mod

使用正则表达式拆分具有相同标题的数据块

在 golang 中联合一个接口和类型

如何将实际上是类型为 reflect.Int32 的类型切片的 interface{} 转换为 int32 的切片?