[英]How to stop one of multilpe of the same goroutine
很快就會發現,我是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)
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.