Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop a goroutine if it is running

Tags:

go

goroutine

I have a question similar to How to stop a goroutine with a small twist. I don't know for sure if the goroutine is running.

var quit = make(chan bool)

func f1() {
    go func() {
        t := time.NewTimer(time.Minute)
        select {
        case <-t.C:
            // Do stuff
        case <-quit:
            return
        }
    }()
}

func f2() {
    quit <- true
}

If f2() is called less than a minute after f1(), then the goroutine returns. However, if it is called later than one minute, the goroutine will have already returned and f2() would block. I want f2() to cancel the goroutine if it is running and do nothing otherwise.

What I'm trying to achieve here is to perform a task if and only if it is not canceled within a minute of creation.

Clarifications:

  • There is nothing to stop f2() from being called more than once.
  • There is only one goroutine running at a time. The caller of f1() will make sure that it's not called more than once per minute.
like image 923
diaa Avatar asked Feb 28 '26 06:02

diaa


1 Answers

Use contexts.

Run f1 with the context which may be cancelled. Run f2 with the associated cancellation function.

func f1(ctx context.Context) {
    go func(ctx context.Context) {
        t := time.NewTimer(time.Minute)
        select {
        case <-t.C:
            // Do stuff
        case <-ctx.Done():
            return
        }
    }(ctx)
}

func f2(cancel context.CancelFunc) {
    cancel()
}

And later, to coordinate the two functions, you would do this:

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

You can also experiment with the context.WithTimeout function to incorporate externally-defined timeouts.

In the case where you don't know whether there is a goroutine running already, you can initialize the ctx and cancel variables like above, but don't pass them into anything. This avoids having to check for nil.

Remember to treat ctx and cancel as variables to be copied, not as references, because you don't want multiple goroutines to share memory - that may cause a race condition.

like image 139
Tyler Kropp Avatar answered Mar 02 '26 20:03

Tyler Kropp



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!