当前位置: 首页 > 面试题库 >

如何停止同一goroutine的multilpe之一

归泽宇
2023-03-14
问题内容

很快就会发现,我是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,并记住它们,以备以后在main
goroutine中使用。甲上下文通常被用作一个消除信号。然后,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)
            }
        }
    }
}


 类似资料:
  • 问题内容: 我有一个goroutine,它调用一个方法,并在通道上传递返回的值: 如何停止这种goroutine? 问题答案: 编辑: 在意识到您的问题是关于将值发送到goroutine中的chan之前,我匆忙编写了此答案。 下面的方法可以与上面建议的其他chan一起使用,或者利用您已经拥有的chan双向的事实,您可以只使用一个… 如果您的goroutine仅用于处理来自chan的项目,则可以使用

  • 问题内容: 我正在尝试停止执行例程,但是我找不到实现此目的的方法。我当时在考虑使用第二个频道,但是如果我从中读取它会阻止它,不是吗?这是一些代码,我希望这些代码可以解释我要做什么。 玩这个东西 问题答案: 实现这一点的方法很少,最简单,最方便的是使用其他渠道,例如: 您也可以研究使用

  • 我正在为Java的一个聊天应用程序做一个服务器。 while循环应该连接到新的客户端,但代码仍然重复连接到第一个客户端,甚至在它连接之后也是如此,从而导致绑定失败错误。我该换什么?

  • 问题内容: 该程序在九次打印后完成: 如何停止进程(例如eclipse中的Java进程),因为它在9秒的时间限制后没有停止? 问题答案: 您遇到的问题是,取消哔声任务后,调度程序会保留活动线程。 如果存在活动的非守护程序线程,则JVM保持活动状态。 它使该线程保持不变的原因是您已在此行中告诉它这样做: 请注意以下文档: -即使在空闲状态下要保留在池中的线​​程数。 因此,您有两种可能的方法来导致J

  • 问题内容: 要找出mysqld的启动命令(使用Mac),我可以这样做: 我得到以下输出,这使我可以启动mysql服务器。 我如何找到必要的命令以从命令行停止mysql? 问题答案: 尝试: 要么: 要么: 要么: 如果 在OSX中 安装 Launchctl,则 可以尝试: MacPorts 注意:重新启动后,此设置将持续存在。 家酿 二进制安装程序 我发现在:https : //stackover

  • 问题内容: 我需要运行一个长时间运行的子进程,并且如果我(出于任何原因)退出父应用程序而将其杀死。 这是代码: 在这里产生明显 它按预期方式工作-子进程被终止。 但这在goroutine中发生: 恐慌仍然发生,但是随后似乎没有被调用,子进程也没有被杀死。 有什么办法解决吗? 更新 我需要一个跨平台的解决方案(至少对于Linux和FreeBSD) 最小示例: 别忘了 (为简便起见,未进行错误检查):