Stopping gorutines via context, basics

Package context defines the Context type, which carries deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes.

Incoming requests to a server should create a Context, and outgoing calls to servers should accept a Context. The chain of function calls between them must propagate the Context, optionally replacing it with a derived Context created using WithCancel, WithDeadline, WithTimeout, or WithValue. When a Context is canceled, all Contexts derived from it are also canceled.

Demo

package main

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

func main() {

	// for synchronize
	ctx, cancel := context.WithCancel(context.Background())
	wg := &sync.WaitGroup{}

	// starting 2 gorutines
	wg.Add(2)
	go coolfunc(ctx, wg, "A")
	go coolfunc(ctx, wg, "B")

	// some application work
	time.Sleep(5 * time.Second)

	// finally: i want to correctly stop all running gorutines
	fmt.Println("let's stop here")
	cancel()

	// wait for all gorutines
	wg.Wait()

	// :)
	fmt.Println("all is done")
}

func coolfunc(ctx context.Context, wg *sync.WaitGroup, name string) {
	fmt.Println(name, "started")
	defer func() {
		fmt.Println(name, "ending")
		wg.Done()
	}()

	for {
		select {
		case <-time.After(time.Second):
			fmt.Println(name, "some work")
		case <-ctx.Done():
			fmt.Println(name, "i am going to down")
			return
		}
	}
}

Output

go run .
A started
B started
A some work
B some work
A some work
B some work
B some work
A some work
A some work
B some work
let's stop here
B i am going to down
A i am going to down
A ending
B ending
all is done
Publikováno v Go