如何停止一个 goroutine
我有一个调用方法并在通道上传递返回值的 goroutine:
ch := make(chan int, 100)
go func(){
for {
ch <- do_stuff()
}
}()
如何停止这样的 goroutine?
I have a goroutine that calls a method, and passes returned value on a channel:
ch := make(chan int, 100)
go func(){
for {
ch <- do_stuff()
}
}()
How do I stop such a goroutine?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
通常,您向 goroutine 传递一个(可能是单独的)信号通道。当您希望 goroutine 停止时,该信号通道用于推送一个值。 Goroutine 定期轮询通道。一旦检测到信号,它就会退出。
Typically, you pass the goroutine a (possibly separate) signal channel. That signal channel is used to push a value into when you want the goroutine to stop. The goroutine polls that channel regularly. As soon as it detects a signal, it quits.
一般来说,您可以创建一个通道并在 goroutine 中接收停止信号。
本例中有两种创建通道的方法。
渠道
上下文。在示例中,我将演示
context.WithCancel
第一个演示,使用
channel
:第二个演示,使用
context
:Generally, you could create a channel and receive a stop signal in the goroutine.
There two way to create channel in this example.
channel
context. In the example I will demo
context.WithCancel
The first demo, use
channel
:The second demo, use
context
:编辑: 我匆忙写下了这个答案,然后才意识到你的问题是关于向 goroutine 内的 chan 发送值。下面的方法可以与上面建议的附加 chan 一起使用,或者使用您已经拥有的 chan 是双向的这一事实,您可以只使用一个...
如果您的 goroutine 仅用于处理来自 chan 的物品,您可以使用“关闭”内置功能和通道的特殊接收表单。
也就是说,一旦您在 chan 上发送完项目,就可以将其关闭。然后在你的 goroutine 中,你会得到一个额外的参数给接收操作符,它显示通道是否已经关闭。
这是一个完整的示例(waitgroup 用于确保进程继续,直到 goroutine 完成):
EDIT: I wrote this answer up in haste, before realizing that your question is about sending values to a chan inside a goroutine. The approach below can be used either with an additional chan as suggested above, or using the fact that the chan you have already is bi-directional, you can use just the one...
If your goroutine exists solely to process the items coming out of the chan, you can make use of the "close" builtin and the special receive form for channels.
That is, once you're done sending items on the chan, you close it. Then inside your goroutine you get an extra parameter to the receive operator that shows whether the channel has been closed.
Here is a complete example (the waitgroup is used to make sure that the process continues until the goroutine completes):
你不能从外部杀死 goroutine。您可以向 Goroutine 发出信号以停止使用通道,但 Goroutine 没有句柄来执行任何类型的元管理。 Goroutine 的目的是合作解决问题,因此杀死一个行为不端的 Goroutine 几乎永远都不是一个足够的反应。如果您想要隔离以实现稳健性,您可能需要一个过程。
You can't kill a goroutine from outside. You can signal a goroutine to stop using a channel, but there's no handle on goroutines to do any sort of meta management. Goroutines are intended to cooperatively solve problems, so killing one that is misbehaving would almost never be an adequate response. If you want isolation for robustness, you probably want a process.
我知道这个答案已经被接受,但我想我应该投入 2 美分。我喜欢使用 tomb 包。它基本上是一个升级的退出通道,但它也做了一些很好的事情,比如传回任何错误。受控制的例程仍然有责任检查远程终止信号。据我所知,如果它行为不当(即:陷入无限循环),则不可能获得 Goroutine 的“id”并杀死它。
这是我测试过的一个简单示例:
输出应如下所示:
I know this answer has already been accepted, but I thought I'd throw my 2cents in. I like to use the tomb package. It's basically a suped up quit channel, but it does nice things like pass back any errors as well. The routine under control still has the responsibility of checking for remote kill signals. Afaik it's not possible to get an "id" of a goroutine and kill it if it's misbehaving (ie: stuck in an infinite loop).
Here's a simple example which I tested:
The output should look like:
就我个人而言,我想在 goroutine 中的通道上使用范围:
https://play.golang.org /p/qt48vvDu8cd
Dave 就此写了一篇很棒的文章:http://dave.cheney.net/2013/04/30/curious-channels。
Personally, I'd like to use range on a channel in a goroutine:
https://play.golang.org/p/qt48vvDu8cd
Dave has written a great post about this: http://dave.cheney.net/2013/04/30/curious-channels.
我使用 close(quitCh) 执行以下操作。使用 close() 它将向所有侦听通道广播退出,在这种情况下,所有 go 例程都在侦听退出
ch
。I do the following, using close(quitCh). Using close() it will broadcast to all listening channels to exit, in this case, all the go routines are listening for the quit
ch
.我将提供一种与此处提供的方法略有不同的方法。
我假设需要停止的 Goroutine 正在执行一些与其他 Goroutine 完全无关的工作。该工作将由默认选择情况表示:
另一个
goroutine
(在我的示例中是main
)决定它应该停止 < code>goroutine 正在执行一些工作。你无法真正杀死goroutine
。即使可以,这也是一个坏主意,因为它可能会使 goroutine 处于不希望的状态。因此,我们必须使用通道来传达有人正在向 Goroutine 发出停止信号。由于
goroutine
将持续执行一些工作。我们将使用一个循环来表示它。当发送停止信号时,goroutine 就会跳出循环。我们可以使用另一个通道向
main
表明 goroutine 已经停止。下面是完整的示例:main
线程生成一个goroutine
来执行某些工作一段时间(在本例中为 5 秒)。当时间到期时,它会向 Goroutine 发送停止信号并等待,直到 Goroutine 完全停止。I am going to offer a slightly different approach than the ones provided here.
I am going to assume the
goroutine
that needs to be stopped is performing some work that is not related at all to othergoroutines
. That work will be represented by thedefault select case
:Another
goroutine
(in my example will be themain
) decides that it should stop thegoroutine
that is performing some work. You cannot really kill thegoroutine
. Even if you could it would be a bad idea because it could leave thegoroutine
in an undesired state. So, we have to use a channel to communicate that someone is signaling to thegoroutine
to stop.Since the
goroutine
will be continuously performing some work. We will use a loop to represent that. And when the stop signal is sent, thegoroutine
breaks out of the loop.We can use another channel to indicate to the
main
that the goroutine has stopped. Here's the full example:The
main
thread spawns agoroutine
to perform some work for some time (in this case 5 seconds). When the time expires, it sends a stop signal to thegoroutine
and waits for it until thegoroutine
is fully stopped.