> I want to be able to terminate each worker independently of others > (i.e. close on worker, wait for it to finish its tasks, but allow > other workers to run if they haven't been signalled to stop).
The solution I use is to have each worker take two parameters: - a channel that will be closed by the main program in order to signal that the worker should terminate; - a channel that will be closd by the worker when it's done. So the worker looks like this: func worker(terminate chan struct{}, done chan struct{}) { defer close(done) outer: for { work(); select { case <-done: break outer default: } } } and the main program looks like this: terminate := make(chan struct{}) done := make(chan struct{}) go worker(terminate, done) ... close(terminate) <-done The terminate channel can be replaced by a context, which is useful if you have a tree of workers to manage: terminate, terminateFn := context.WithCancel(context.Background()) done := make(chan struct{}) go worker(terminate, done) ... terminateFn() <-done Or perhaps with a timeout in case a worker gets stuck: terminate, terminateFn := context.WithCancel(context.Background()) done := make(chan struct{}) go worker(terminate, done) ... terminateFn() timeout := time.NewTimer(5 * time.Second) select { case <-done: timeout.Cancel() case <-timeout.C: log.Println("Worker failed to terminate within 5s") } -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/87y28jnobp.fsf%40pirx.irif.fr.