Go 如何优雅的关闭goroutine

1. Context包方式

package main

import (
	"context"
	"fmt"
	"sync"
	"time"
)
var wg =new(sync.WaitGroup) //创建一个等待组

func main(){
	ctx,cancel := context.WithCancel(context.Background())
	wg.Add(1) //等待组计数+1 
	go work1(ctx) //跑一个work1 goroutine  
	exit_with_second(5,cancel) //设置sleep 5秒执行cancel()
	wg.Wait() //等待组计数为0 释放阻塞
}

func work1(ctx context.Context){
LOOP:
	for{
		time.Sleep(time.Second*1)
		select {
		case x := <-ctx.Done():
			fmt.Println("work1 rev :",x)
			break LOOP
		default:
			fmt.Println("work1...")
		}
	}
	fmt.Println("work1 done ...")
	wg.Done() //等待组计数-1
}

func exit_with_second(s int,f context.CancelFunc){
	time.Sleep(time.Second * time.Duration(s))
	f() //执行
}

2. Channel方式

package main

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


var wg = new(sync.WaitGroup)

func main(){
	var ch = make(chan int) //创建一个管道
	defer close(ch) //程序退出前关闭管道
	wg.Add(1)
	go work1(ch)   //执行一个work1 goroutine
	sendnumber(5,ch)  
	wg.Wait()
}


func work1(c chan int){
	LOOP:
		for  {
			time.Sleep(time.Second * 1)
			select {
			case n := <-c :
				fmt.Println("work1 rev:",n)
				break LOOP   // 从管道接收到数字1 退出循环
			default:
				fmt.Println("work1 ...")
			}
		}
		fmt.Println("work1 done")
		wg.Done()
}

func sendnumber(n int,c chan int){
	time.Sleep(time.Second * time.Duration(n))
	c <- 1 // 往管道发送数字1
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值