上篇文章中,我们已经学习了使用context实现控制多个goroutine的退出。

本文将继续介绍如何使用context实现超时情况下,让多个goroutine退出。

例子

首先,启动3个goroutine,分别为1,2,3。这3个goroutine又分别启动一个goroutine。

一共有6个goroutine,它们之间关系如下:

  • 1

    • 11
  • 2
    • 21
  • 3
    • 31

task1,2,3被限制在指定时间内结束,即50ms。

如果不能按时结束,会触发超时操作,这样,task 1、2、3接收到超时信号,取消自己启动的goroutine(即task11,21,31),然后退出。

最后,所有的goroutine都退出了。

代码如下:

ackage main

import (
"context"
"fmt"
"time"
) func PrintTask(ctx context.Context, taskName string) { for { select { case <- ctx.Done():
fmt.Println("task:", taskName, "ctx error:", ctx.Err()," then task exit...")
return
default:
time.Sleep(1*time.Second)
fmt.Println("task:", taskName, " doing something...")
} } } func mainTask(ctx context.Context, taskName string) { ctx1, cancel := context.WithCancel(ctx)
defer cancel() // create a new task
newTaskName := taskName + "1"
go PrintTask(ctx1, newTaskName) for { select { case <- ctx.Done():
fmt.Println("task:", taskName, "ctx error:", ctx.Err()," then task exit...")
return
default:
time.Sleep(1*time.Second)
fmt.Println("task:", taskName, " doing something...")
} } } func main() { ctx := context.Background()
timeout := 50*time.Millisecond
ctx, _ = context.WithTimeout(ctx, timeout) go mainTask(ctx, "1")
go mainTask(ctx, "2")
go mainTask(ctx, "3") select{
case <-ctx.Done():
// timeout
fmt.Println("main task error:", ctx.Err())
} fmt.Println("main exit...")
time.Sleep(3*time.Second)
}

输出

main task error: context deadline exceeded
main exit...
task: 21 doing something...
task: 1 doing something...
task: 21 ctx error: context deadline exceeded then task exit...
task: 3 doing something...
task: 3 ctx error: context deadline exceeded then task exit...
task: 1 ctx error: context deadline exceeded then task exit...
task: 11 doing something...
task: 11 ctx error: context deadline exceeded then task exit...
task: 31 doing something...
task: 2 doing something...
task: 31 ctx error: context deadline exceeded then task exit...
task: 2 ctx error: context deadline exceeded then task exit...

golang context学习记录2的更多相关文章

  1. golang context学习记录1

    1.前言 一个请求,可能涉及多个API调用,多个goroutine,如何在多个API 之间,以及多个goroutine之间协作和传递信息,就是一个问题. 比如一个网络请求Request,需要开启一些g ...

  2. golang "%p"学习记录随笔

    对于获取slice的指针地址, 通过unsafe.Pointer 和 "%p"占位符两种方式得到的地址是不同的 s := make([]int, 1) t.Log(unsafe.P ...

  3. 【golang学习记录】环境搭建

    [golang学习记录]环境搭建 一. 概述 本文是[golang学习记录]系列文章的第一篇,安装Go语言及搭建Go语言开发环境,接下来将详细记录自己学习 go 语言的过程,一方面是为了巩固自己学到的 ...

  4. Golang Context 的原理与实战

    本文让我们一起来学习 golang Context 的使用和标准库中的Context的实现. golang context 包 一开始只是 Google 内部使用的一个 Golang 包,在 Gola ...

  5. Quartz 学习记录1

    原因 公司有一些批量定时任务可能需要在夜间执行,用的是quartz和spring batch两个框架.quartz是个定时任务框架,spring batch是个批处理框架. 虽然我自己的小玩意儿平时不 ...

  6. Spring学习记录(九)---通过工厂方法配置bean

    1. 使用静态工厂方法创建Bean,用到一个工厂类 例子:一个Car类,有brand和price属性. package com.guigu.spring.factory; public class C ...

  7. 【转】BLE 学习记录

    原文网址:http://m.blog.csdn.net/blog/chiooo/43985401 BLE 学习记录 ANROID BLE 开发,基于 bluetoothlegatt 分析 mBluet ...

  8. 我的Spring学习记录(二)

    本篇就简单的说一下Bean的装配和AOP 本篇的项目是在上一篇我的Spring学习记录(一) 中项目的基础上进行开发的 1. 使用setter方法和构造方法装配Bean 1.1 前期准备 使用sett ...

  9. 我的Spring学习记录(四)

    虽然Spring管理这我们的Bean很方便,但是,我们需要使用xml配置大量的Bean信息,告诉Spring我们要干嘛,这还是挺烦的,毕竟当我们的Bean随之增多的话,xml的各种配置会让人很头疼. ...

随机推荐

  1. 多线程编程-- part 6 共享锁和ReentrantReadWriteLock

    介绍: ReadWriteLock,顾名思义,是读写锁.它维护了一对相关的锁 — — “读取锁”和“写入锁”,一个用于读取操作,另一个用于写入操作.(1)“读取锁”用于只读操作,它是“共享锁”,能同时 ...

  2. js 格式化 json 字符串

    1.JSON.stringify的三个参数 var json = {"@odata.context":"$metadata#AddTableOne_466281s&quo ...

  3. linux中查看文件夹结构的小工具

    tree命令是Linux/UNIX系统中常用的命令,可以非常方便地查看文件夹的结构,并且以树形目录的形式展示 在Ubuntu中安装 sudo apt-get install tree 在CentOS中 ...

  4. 享元模式<Flyweight Pattern>

    1.What-是什么?   享元模式是一种轻量级的结构型模式.旨在以共享的方式高效的支持大量的细粒度对象的复用.要求能够共享的对象必须是细粒度对象,这些对象比较相似,状态变化小. 2.Why-为什么? ...

  5. 从FBV到CBV四(访问频率限制)

    比如我们有一个用户大转盘抽奖的功能,需要规定用户在一个小时内只能抽奖3次,那此时对接口的访问频率限制就显得尤为重要 其实在restframework中已经为我们提供了频率限制的组件 先捋一下请求到AP ...

  6. centso 7 Keepalived 配置脚本

    #!/bin/bash #This is keepalived bashshell. #MASTER/BACKUP yum install -y openssl openssl-devel keepa ...

  7. tornada-基础

    回想Django的部署方式 以Django为代表的python web应用部署时采用wsgi协议与服务器对接(被服务器托管),而这类服务器通常都是基于多线程的,也就是说每一个网络请求服务器都会有一个对 ...

  8. c# HttpClient和HttpWebRequest添加Basic类型的Authentication认证

    c#项目中用到调用客户接口,basic身份认证,base64格式加密(用户名:密码)贴上代码以备后用 1.使用HttpClient实现basic身份认证 using (HttpClient clien ...

  9. 解决c#distinct不好用的问题

    当一个结合中想根据某一个字段做去重方法时使用以下代码 IQueryable 继承自IEnumerable 先举例: #region linq to object List<People> ...

  10. 对JS继承的研究--------------引用

    问:类继承和原型继承不是同一回事儿吗,只是风格选择而已? 答:不是! 类继承和原型继承不论从本质上还是从语法上来说,都是两个截然不同的概念. 二者之间有着区分彼此的本质性特征.要完全看懂本文,你必须牢 ...