登录
首页 >  Golang >  Go问答

如何停止同一 goroutine 的多个进程之一

来源:stackoverflow

时间:2024-04-07 09:57:34 477浏览 收藏

大家好,我们又见面了啊~本文《如何停止同一 goroutine 的多个进程之一》的内容中将会涉及到等等。如果你正在学习Golang相关知识,欢迎关注我,以后会给大家带来更多Golang相关文章,希望我们能一起进步!下面就开始本文的正式内容~

问题内容

很快就会显而易见,我是一个 golang n00b。

我有一些基于事件通道启动 goroutine 的 go 代码。假设它启动了 2 个 goroutine,因为我们收到了 2 个 start 类型的事件。

goroutine 以 uri 作为参数启动,这给了我们一些独特的东西。

稍后我们收到一个 stop 类型的事件。

如何停止使用相同 uri 启动的 goroutine?

for {
            select {
            case event := <-eventCh:
                if event.Entry != nil {
                    switch event.Action {
                    case foo.START:
                        log.Println("uri: ", event.Entry.URI)

                        go func(c chan []byte, u string) error{
                            //awesome goroutine code
                        }(myChan, event.Entry.URI)

                    case foo.STOP:
                        log.Println("uri: ", event.Entry.URI)
                        //I'd like to terminate the goroutine that matches event.Entry.URI
                    }
                }
            }
        }

解决方案


你无法“从外部”停止 goroutine。您必须向每个 goroutine 传递某种取消信号,并记住它们以便稍后在主 goroutine 中使用。 Context 通常用作取消信号。然后 goroutine 必须检查是否取消并自动退出:

package main

import (
    "context"
)

type Event struct {
    Action string
    URI    string
}

func main() {
    var eventCh chan Event

    ctx := context.Background()

    cancels := make(map[string]context.CancelFunc) // Maps URIs to cancellation functions.

    for event := range eventCh {
        switch event.Action {
        case "START":
            if cancels[event.URI] != nil {
                panic("duplicate URI: " + event.URI)
            }

            ctx, cancel := context.WithCancel(ctx)
            cancels[event.URI] = cancel
            defer cancel() // cancel must always be called to free resources.

            go func(u string) {
                // Awesome goroutine code

                // Check ctx.Done or ctx.Err in strategic places and return if done.
                select {
                case <-ctx.Done():
                    return
                default:
                }

                // More awesome goroutine code

                if ctx.Err() != nil {
                    return
                }

                // Even more awesome goroutine code

            }(event.URI)

        case "STOP":
            if cancel, ok := cancels[event.URI]; ok {
                cancel()
                delete(cancels, event.URI)
            }
        }
    }
}

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>