Stop all recursive functions in goroutine

When looking at a goroutine that performs a recursive function, I want to send a signal to stop these recursive functions. This is a function (functionality is not important):

func RecursiveFunc(x int, depth int, quit chan bool) int {

    if depth == 0 {
        return 1
    }

    if quit != nil {
        select {
        case <-quit:
            return 0
        default:
        }
    }

    total := 0

    for i := 0; i < x; i++ {

        y := RecursiveFunc(x, depth - 1, quit)

        if y > 0 {
            total += y
        }

    }

    return total
}

This function can take a lot of time, and I want to stop it after sending the exit signal and use the result (whatever it is). For start:

import (
    "fmt"
    "time"
    "sync"
)

func main() {

    quit := make(chan bool)
    wg := &sync.WaitGroup{}
    result := -1

    go func() {
        defer wg.Done()
        wg.Add(1)
        result = RecursiveFunc(5, 20, quit)
    }()

    time.Sleep(10 * time.Millisecond)

    close(quit) // Using `quit <- true` doesn't work

    wg.Wait()

    fmt.Println(result)
}

To stop goroutine, I use the say channel quit, and after closing it, the program works well, however I don’t really want to close the channel, and I just want to send a signal quit <- true. However, it quit <- truedoes not work, and I probably left only one instance of recursion.

How can I stop all instances of a recursive function by sending an exit signal?

+4
2

, , context.

context.Context , , cancel " " , Done() context.Context, , , select.

context.Context:

func RecursiveFunc(ctx context.Context, x int, depth int) int {

    if depth == 0 {
        return 1
    }

    select {
    case <-ctx.Done():
        return 0
    default:
    }

    total := 0

    for i := 0; i < x; i++ {

        y := RecursiveFunc(ctx, x, depth-1)

        if y > 0 {
            total += y
        }

    }

    return total
}

:

func main() {

    wg := &sync.WaitGroup{}
    result := -1

    ctx, cancel := context.WithCancel(context.Background())

    go func() {
        defer wg.Done()
        wg.Add(1)
        result = RecursiveFunc(ctx, 5, 20)
    }()

    time.Sleep(10 * time.Millisecond)

    cancel()

    wg.Wait()

    fmt.Println(result)
}
+4

, .

var finishIt bool

func RecursiveFunc(x int, depth int, quit chan bool) int {
   if finishIt {
    return 0
   }
//other code here
}


//some code here, but than we decide to stop it
finishIt = true
-1

Source: https://habr.com/ru/post/1671502/


All Articles