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

如何向goroutine发出信号以使其停止运行?

傅志诚
2023-03-14
问题内容

我正在尝试停止执行例程,但是我找不到实现此目的的方法。我当时在考虑使用第二个频道,但是如果我从中读取它会阻止它,不是吗?这是一些代码,我希望这些代码可以解释我要做什么。

package main

import "fmt"
import "time"

func main() {

    var tooLate bool

    proCh := make(chan string)

    go func() {
        for {
               fmt.Println("working")
        //if is tooLate we stop/return it
            if tooLate { 
            fmt.Println("stopped")
                return
            }
       //processing some data and send the result on proCh
            time.Sleep(2 * time.Second)
            proCh <- "processed"
            fmt.Println("done here")

        }
    }()
    select {
    case proc := <-proCh:
        fmt.Println(proc)
    case <-time.After(1 * time.Second):
        // somehow send tooLate <- true
        //so that we can stop the go routine running
        fmt.Println("too late")
    }

    time.Sleep(4 * time.Second)
    fmt.Println("finish\n")
}

玩这个东西


问题答案:

实现这一点的方法很少,最简单,最方便的是使用其他渠道,例如:

func main() {
    tooLate := make(chan struct{})
    proCh := make(chan string)

    go func() {
        for {
            fmt.Println("working")
            time.Sleep(1 * time.Second)
            select {
            case <-tooLate:
                fmt.Println("stopped")
                return
            case proCh <- "processed": //this why it won't block the goroutine if the timer expirerd.
            default: // adding default will make it not block
            }
            fmt.Println("done here")

        }
    }()
    select {
    case proc := <-proCh:
        fmt.Println(proc)
    case <-time.After(1 * time.Second):
        fmt.Println("too late")
        close(tooLate)
    }

    time.Sleep(4 * time.Second)
    fmt.Println("finish\n")
}

playground

您也可以研究使用 sync.Cond



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

  • 我从两个通道中获得了多个的goroutine:一个chan提供数据,一个chan提供信号(类似于done/quit通道)。 我使用signals通道来捕获信号(杀死)并优雅地关闭Goroutines。 当我终止正在运行的进程时,我会看到来自的打印消息。我预计,一旦通道关闭,goroutines将thecase并返回。 但他们不停地奔跑;它们继续处理中的项。好像被忽视了。我在这里漏掉了什么?频道不是

  • 问题内容: 很快就会发现,我是golang n00b。 我有一些基于事件通道启动goroutine的go代码。假设它启动了2个goroutine,因为我们收到了2个START类型的事件。 goroutine以uri作为参数开始,这给了我们一些独特之处。 稍后,我们将收到一个STOP类型的事件。 如何停止以相同uri开始的goroutine? 问题答案: 您无法从外部停止goroutine。您必须将

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

  • 我想在Project Retor中尝试。根据描述,它用于 订阅此单声道并无限期地阻止,直到收到下一个信号或单声道完成空 我尝试了以下方法。 我希望看到“外链”在30年代延迟之前打印出来。然而,我必须等待30多岁。 没有收到信号吗?当收到信号时,程序块应该停止?这是发送信号的正确方式吗?

  • 问题内容: 我为进程编写了一个信号处理程序,然后编写了fork(),该信号处理程序将同时应用于父进程和子进程。如果我将子进程替换为“ exec”,则信号处理程序将不再可用。 我知道发生这种情况是因为“ exec”调用将使用其自身覆盖子进程地址空间。我只想知道即使在“ exec”调用之后是否有一种方法可以使信号处理程序正常工作? 问题答案: 否。从页面: execve()不会成功返回,并且调用过程的