Как остановить goroutine, если мы не в состоянии слушать от канала, переданного этой подпрограмме - PullRequest
0 голосов
/ 01 февраля 2019

Я столкнулся с проблемой, связанной с goroutines.Предположим, что есть канал, и мы пропустили этот канал через goroutine из main.Теперь, если мы не сможем прослушать этот канал с основного (в случае возврата / паники перед прослушиванием).Горутин не останавливается.Как остановить эту процедуру в случае ошибки?

В случае многократного вызова функции в процедуре количество подпрограмм продолжает увеличиваться.

package main

import (
    "fmt"
    "runtime"
)

func test(a chan string) {
    defer func() {
        close(a)
        fmt.Println("channel close")
    }()
    fmt.Println("sending to channel")
    a <- "1"
    fmt.Println("sent to channel")
}

func method() string {

    fmt.Println("method starting no. of routine=>",
        runtime.NumGoroutine())
    b := make(chan string)

    go test(b)
    fmt.Println("method current no. of routine=>",
        runtime.NumGoroutine())

    return "error" //if this is executed the routines keeps on
    //increasing
    a := <-b
    return a
}

func main() {
    defer fmt.Println("final main no. of routine=>",
        runtime.NumGoroutine())
    i := 0
    //firing 10 request for method
    for {
        if i < 10 {
               fmt.Println(method())
               i++
        } else {
               break
        }

    }
}

Вывод:

method starting no. of routine=> 1

method current no. of routine=> 2

error

method starting no. of routine=> 2

method current no. of routine=> 3

error

method starting no. of routine=> 3

method current no. of routine=> 4

error

..... продолжает расти, как это

1 Ответ

0 голосов
/ 01 февраля 2019

рутина может быть остановлена ​​контекстом.Прежде чем использовать контекст, вы должны знать, что только подпрограммы с циклом ожидают остановки, эти прерываемые подпрограммы останавливать не нужно.

пример контекста:

func main(){
    ctx, cancel := context.WithCancel(context.Background())
    go func(c context.Context){
        for {
            select{
                case <-c.Done():
                   fmt.Println("exit success")
                default:
                   // service
                   fmt.Println("my logic service loop")
            }    
        }
    }(ctx)
    time.Sleep(5 * time.Second)
   cancel()
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...