golang协程的最佳实践与context包的基本使用

1.协程最佳实践,多个协程并发求素数

点击查看代码
var wg sync.WaitGroup

func Prime(num int) bool {
	if num == 1 {
		return false
	}
	for i := 2; i*i <= num; i++ {
		if num%i == 0 {
			return false
		}
	}
	return true
}

func test1(ch chan int) {
	for i := 1; i <= 100; i++ {
		ch <- i
	}
	close(ch)
	defer wg.Done()
}

func test2(ch chan int, ch2 chan int, exitChan chan bool) {
	for v := range ch {
		if Prime(v) {
			ch2 <- v
		}
	}
	exitChan <- true
	defer wg.Done()
}

func test3(ch2 chan int, exitChan chan bool) {
	for v := range ch2 {
		fmt.Println(v)
	}
	exitChan <- true
	defer wg.Done()
}

func main() {
	var ch = make(chan int, 20)
	var ch2 = make(chan int, 20)
	var exitChan = make(chan bool, 5)
	//for i := 0; i < 5; i++ {
	wg.Add(1)
	go test1(ch)
	//}
	for i := 0; i < 5; i++ {
		wg.Add(1)
		go test2(ch, ch2, exitChan)
	}
	//for i := 0; i < 5; i++ {
	wg.Add(1)
	go test3(ch2, exitChan)
	//}
	wg.Add(1)
	go func() {
		for i := 0; i < 5; i++ {
			<-exitChan
		}
		close(ch2)
	}()
	wg.Done()

	wg.Wait()
}
ch管道用于存放1~100的数字,放完后关闭,ch2管道用于统计素数,test3()函数用于从ch2管道取出数据并打印

2.Context包的基本使用
使用context包目的是管理协程的生命周期,以及管理多级协程,以下为Context()基本函数的使用

点击查看代码
func test(msg chan int, ctx context.Context) {
	t := time.Tick(time.Second)
	for range t {
		select {
		case n := <-msg:
			fmt.Println("job", n, "done")
		case <-ctx.Done():
			fmt.Println("return...", ctx.Value(k))
			return
		}
	}
}

type str string

var k str = "name"
var v str = "YueSe"

func main() {
	// ctx, clear := context.WithCancel(context.Background())
	ctx := context.WithValue(context.Background(), k, v)
	ctx, clear := context.WithDeadline(ctx, time.Now().Add(time.Second*5))
	var message = make(chan int)
	// var flag = make(chan bool)
	go test(message, ctx)
	for i := 0; i < 10; i++ {
		message <- i
	}
	clear()
	// flag <- true
	time.Sleep(time.Second)
	fmt.Println("all done")

}

Done

posted @ 2024-08-07 15:22  yuese00  阅读(8)  评论(0编辑  收藏  举报