go 主协程等待子协程执行完毕再执行方法

go 主协程通知子协程退出方法-go面试

方式一:用全局变量

主goroutine使用全局变量通知子goroutine退出

func f() {
	defer wg.Done()
	for {
		fmt.Println("中国")
		time.Sleep(time.Millisecond * 500)
		if notify {
			break
		}
	}
}

func main() {
	wg.Add(1)
	go f()
	time.Sleep(time.Second * 5)
	notify = true
	wg.Wait()
}
方式二:用channel+select

通过子goroutine接收channel的值让goroutine退出

var wg sync.WaitGroup
var exitChan = make(chan bool, 1)

func f() {
	defer wg.Done()
LOOP:
	for {
		fmt.Println("中国")
		time.Sleep(time.Millisecond * 500)
		select {
		case <-exitChan:
			break LOOP
		default:
		}
	}
}

func main() {
	wg.Add(1)
	go f()
	time.Sleep(time.Second * 5)
	exitChan <- true
	wg.Wait()
}

但是在某些场景下,例如处理一个请求衍生了很多协程,这些协程之间是相互关联的:需要共享一些全局变量、有共同的 deadline 等,而且可以同时被关闭。再用 channel+select 就会比较麻烦,这时就可以通过 context 来实现。
在这里插入图片描述
在这里停止worker1的情况下可以使用channel+select,而停止worker2,3的情况下,channel+select就显得不是非常友好,使用context就可以。

一句话:context 用来解决 goroutine 之间退出通知、元数据传递的功能。

方式三:用context

context方法本质上也是channel,只不过进一步包装,更具有实用性

var wg sync.WaitGroup
func f2(ctx context.Context) {
	defer wg.Done()
LOOP:
	for {
		fmt.Println("上海")
		time.Sleep(time.Millisecond * 500)
		select {
		case <-ctx.Done():
			break LOOP
		default:
		}
	}
}
func f(ctx context.Context) {
	defer wg.Done()
	f2(ctx)
LOOP:
	for {
		fmt.Println("中国")
		time.Sleep(time.Millisecond * 500)
		select {
		case <-ctx.Done():
			break LOOP
		default:
		}
	}
}

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel() //通知子goroutine结束
	wg.Add(1)
	go f(ctx)
	time.Sleep(time.Second * 5)
	wg.Wait()
}

go 主协程等待子协程执行完毕再执行方法

方法一:sync.WaitGroup
方法二:contextContext
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Go语言中,多协程执行的顺序并不是固定的,每一次运行的结果都可能不同。通常情况下,我们无法确定哪个协程会先执行完毕。 然而,如果我们需要确保所有的协程执行完毕之后才能进行下一步的操作,我们可以使用WaitGroup来实现这个目的。WaitGroup是Go语言的一个同步原语,它可以用来等待一组协程的完成。 在使用WaitGroup时,我们需要在协程中创建一个WaitGroup对象,并设置需要等待协程数量。然后,在每个协程的最后调用Done()方法,表示该协程已经执行完毕。最后,我们在协程中调用Wait()方法,这会导致协程在所有协程执行完毕之前一直等待。 下面是一个使用WaitGroup的例: ```go package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup // 设置需要等待协程数量 wg.Add(2) // 第一个协程 go func() { defer wg.Done() // 协程执行的任务 fmt.Println("协程1执行完毕") }() // 第二个协程 go func() { defer wg.Done() // 协程执行的任务 fmt.Println("协程2执行完毕") }() // 等待所有协程执行完毕 wg.Wait() // 所有协程执行完毕后才会执行下面的代码 fmt.Println("所有协程执行完毕") } ``` 在上述代码中,我们创建了一个WaitGroup对象`wg`,然后通过`wg.Add(2)`告诉它有两个协程需要等待。在每个协程的最后,我们都调用了`wg.Done()`表示该协程已经执行完毕。最后,我们通过`wg.Wait()`使协程等待所有协程执行完毕。 这样,当所有的协程执行完毕之后,协程才会执行下面的代码。这样就保证了所有协程执行完毕之后才执行

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值