如果一个 Goroutine 正在运行,请停止它

我有一个类似于如何用一个小扭曲来阻止Goroutine的问题。我不确定戈鲁丁是否正在运行。


var quit = make(chan bool)


func f1() {

    go func() {

        t := time.NewTimer(time.Minute)

        select {

        case <-t.C:

            // Do stuff

        case <-quit:

            return

        }

    }()

}


func f2() {

    quit <- true

}

如果在不到一分钟后被调用,则 goroutine 返回。但是,如果它在一分钟后被调用,则goroutine将已经返回并会阻塞。如果 goroutine 正在运行,我想取消它,否则不执行任何操作。f2()f1()f2()f2()


我在这里试图实现的是执行一项任务,当且仅当它在创建后的一分钟内没有被取消。

澄清:

  • 没有什么可以阻止被多次调用。f2()

  • 一次只有一个戈鲁丁在奔跑。的调用方将确保每分钟调用的次数不超过一次。f1()


SMILET
浏览 108回答 2
2回答

慕仙森

使用上下文。使用可能被取消的上下文运行。使用关联的取消函数运行。f1f2func f1(ctx context.Context) {&nbsp; &nbsp; go func(ctx context.Context) {&nbsp; &nbsp; &nbsp; &nbsp; t := time.NewTimer(time.Minute)&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-t.C:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Do stuff&nbsp; &nbsp; &nbsp; &nbsp; case <-ctx.Done():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }(ctx)}func f2(cancel context.CancelFunc) {&nbsp; &nbsp; cancel()}稍后,为了协调这两个函数,您将执行以下操作:&nbsp; &nbsp; ctx, cancel := context.WithCancel(context.Background())&nbsp; &nbsp; f1(ctx)&nbsp; &nbsp; f2(cancel)您还可以试验该函数以合并外部定义的超时。context.WithTimeout如果您不知道是否已经有一个goroutine在运行,您可以像上面那样初始化和变量,但不要将它们传递给任何东西。这样就避免了必须检查 .ctxcancelnil请记住将 ctx 和 cancel 视为要复制的变量,而不是引用,因为您不希望多个 goroutine 共享内存 - 这可能会导致争用条件。

jeck猫

您可以为通道指定缓冲区大小为 1。这意味着您可以在不阻塞的情况下向其发送一个值,即使该值没有立即(或根本没有收到)也是如此。var&nbsp;quit&nbsp;=&nbsp;make(chan&nbsp;bool,&nbsp;1)我认为最好的答案是更好的,这只是另一种可以转化为其他情况的解决方案。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go