簡體   English   中英

如何停止同一goroutine的multilpe之一

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM