为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
SMILET 2022-08-24 15:44:30
我有一个类似于如何用一个小扭曲来阻止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()
查看完整描述

2 回答

?
慕仙森

TA贡献1827条经验 获得超7个赞

使用上下文。


使用可能被取消的上下文运行。使用关联的取消函数运行。f1f2


func f1(ctx context.Context) {

    go func(ctx context.Context) {

        t := time.NewTimer(time.Minute)

        select {

        case <-t.C:

            // Do stuff

        case <-ctx.Done():

            return

        }

    }(ctx)

}


func f2(cancel context.CancelFunc) {

    cancel()

}

稍后,为了协调这两个函数,您将执行以下操作:


    ctx, cancel := context.WithCancel(context.Background())

    f1(ctx)

    f2(cancel)

您还可以试验该函数以合并外部定义的超时。context.WithTimeout


如果您不知道是否已经有一个goroutine在运行,您可以像上面那样初始化和变量,但不要将它们传递给任何东西。这样就避免了必须检查 .ctxcancelnil


请记住将 ctx 和 cancel 视为要复制的变量,而不是引用,因为您不希望多个 goroutine 共享内存 - 这可能会导致争用条件。


查看完整回答
反对 回复 2022-08-24
?
jeck猫

TA贡献1909条经验 获得超7个赞

您可以为通道指定缓冲区大小为 1。这意味着您可以在不阻塞的情况下向其发送一个值,即使该值没有立即(或根本没有收到)也是如此。

var quit = make(chan bool, 1)

我认为最好的答案是更好的,这只是另一种可以转化为其他情况的解决方案。


查看完整回答
反对 回复 2022-08-24
  • 2 回答
  • 0 关注
  • 80 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信