Go语言:context使用的示例

context主要是用于多个协程之间的统一控制,主要包括统一取消和统一超时。下面是关于context对多个协程进行统一控制的示例:

 假设有这样一个应用场景,一个公司(main)有一名经理(manager)和两名工人(worker),公司下班(main exit)有两种可能:一:工人(worker)的工作时间已经达到合同约定的最大时长;二:经理(manager)提前叫停收工。两种可能满足其中一个即可下班。

示例:

package main

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

//worker工作的最大时长,超过这个时长worker自行收工无需等待manager叫停
const MAX_WORKING_DURATION = 5 * time.Second
//达到实际工作时长后,manager可以提前叫停
const ACTUAL_WORKING_DURATION = 10 * time.Second

func main() {
	ctxWithCancel, cancel := context.WithTimeout(context.Background(), MAX_WORKING_DURATION)

	go worker(ctxWithCancel, "[1]")
	go worker(ctxWithCancel, "[2]")

	go manager(cancel)

	<-ctxWithCancel.Done()
	//暂停1秒便于协程的打印输出
	time.Sleep(1 * time.Second)
	fmt.Println("company closed")
}

func manager(cancel func()){
	time.Sleep(ACTUAL_WORKING_DURATION)
	fmt.Println("manager called cancel()")
	cancel()
}

func worker(ctxWithCancel context.Context, name string) {
	for {
		select {
		case <-ctxWithCancel.Done():
			fmt.Println(name, "return for ctxWithCancel.Done()")
			return
		default:
			fmt.Println(name, "working")
		}
		time.Sleep(1 * time.Second)
	}
}

输出:

[1] working
[2] working
[2] working
[1] working
[1] working
[2] working
[2] working
[1] working
[1] working
[2] working
[1] return for ctxWithCancel.Done()
[2] return for ctxWithCancel.Done()
company closed

可见,这次下班是因为ctxWithCancel的计时器到点引起的。

把实际工作时长改成2秒,最大工作时长不变,再运行一次

//worker工作的最大时长,超过这个时长worker自行收工无需等待manager叫停
const MAX_WORKING_DURATION = 5 * time.Second
//达到实际工作时长后,manager可以提前叫停
const ACTUAL_WORKING_DURATION = 2 * time.Second

输出:

[1] working
[2] working
[2] working
[1] working
manager called cancel()
[1] return for ctxWithCancel.Done()
[2] return for ctxWithCancel.Done()
company closed

可见,worker只工作了2秒就被manager提前叫停了。

至于为什么要用context而不是用计时器加通道来实现,请见另一篇文章《Go语言:为什么要使用上下文(context)而不是计时器(timer)加通道(channel)的方式来控制协程》

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值