如何杀死阻塞go routine

How to kill blocking go routine

所以我正在尝试实现一个简单地监听 Redis 订阅的 go 例程(我为此使用 Go-redis 库)然后发送消息 在 recieves/processes Redis 消息之后的频道上。

像这样:

func foo(redis *redis.Client, comm chan HandlerSignal) {

    ...

    for {
        msg, err := pubsub.ReceiveMessage()
        sig := HandlerSignal{msg}
        comm <- sig
    }
}

但我想不出最好的方法来告诉 return go 例程阻塞并等待 redis 消息时。

有谁知道这种情况的常见做法,还是我的做法全错了?

正如我在这里看到的:https://github.com/go-redis/redis/blob/v3.2.30/pubsub.go#L253 pubsub.ReceiveMessage() 在内部使用 ReceiveTimeout(5 * time.Second)。为什么不使用相同的功能(如@Tomasz Kłak 所建议的那样)?

func foo(redis *redis.Client, comm chan HandlerSignal, quit chan struct{}) {
    ...
    for {

        select {
        case <-quit:
            return
        default:
            msg, err := pubsub.ReceiveTimeout(5 * time.Second)
            sig := HandlerSignal{msg}
            comm <- sig    
        }
    }
}

由于 ReceiveTimeout 将在接下来的 5 秒内阻止例程,因此 default case 不会饱和。