Home  >  Article  >  Backend Development  >  Go - forever stop loop with context

Go - forever stop loop with context

WBOY
WBOYforward
2024-02-06 08:45:07312browse

Go - 永远停止带有上下文的循环

Question content

I have an asynchronous process that is supposed to last forever, like this:

func asyncforevertask() {
  for {
    anytask()
  }
}

func main() {
  go asyncforevertask()

  server.run(8080)
}

I want to be able to stop this for loop when a request reaches the server.

I know I need to use context.withcancel(), but I don't know how to integrate it to make it work. I know the following syntax:

for {
  select {
  case <-ctx.Done:
    return
  case <-otherCh:
    // do smh.
  }
}

But asyncforevertask is not run by a signal from any otherch, but it runs forever. I'm a newbie and any kind of help is greatly appreciated.


Correct Answer


You can use channels to do this:

var stopasync = make(chan struct{})

func asyncforevertask() {
  for {
    select {
      case <-stopasync:
         return
      default:
    }
    anytask()
  }
}

To cancel, simply close the channel. You have to make sure the channel is closed only once, otherwise you will panic.

You can also do this via context:

func main() {
   ctx,cancel:=context.withcancel(context.background())
   go asyncforevertask(ctx)
   ...
}

func asyncforevertask(ctx context.context) {
  for {
    select {
      case <-ctx.done():
         return
      default:
    }
    anytask()
  }
}

or:

func asyncforevertask(ctx context.context) {
  for {
    if ctx.err()!=nil {
       return
    }
    anytask()
  }

To stop, call the returned cancel function:

...
cancel()

If you also need to stop anytask, you must always check for channel close or context close and return from the task.

The above is the detailed content of Go - forever stop loop with context. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete