上篇文章中,我们已经学习了使用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. Linux Exploit系列之一 典型的基于堆栈的缓冲区溢出

    Linux (x86) Exploit 开发系列教程之一(典型的基于堆栈的缓冲区溢出) Note:本文大部分来自于看雪hackyzh的中文翻译,加入了一些自己的理解 典型的基于堆栈的缓冲区溢出 虚拟机 ...

  2. ab测试工具的使用

    下载地址:http://httpd.apache.org/download.cgi#apache24 编译安装后在安装目录bin下可以找到ab执行程序 基本用法: ab -n 5000 -c 1000 ...

  3. 【异常】~/.bash_profile:source:44: no such file or directory: /usr/local/Cellar/nvm/0.34.0/nvm.sh

    1 异常信息 /Users/zhangjin/.bash_profile:source:: no such file or directory: /usr/local/Cellar/nvm//nvm. ...

  4. CDN和浏览器缓存

    1,CDN 旨在解决的最重要的问题是什么,我们称之为网络延迟,通过网络获取资源总是比从本地获取慢,无论服务器是在同一个局域网中还是位于世界的另一个角落,都是如此.这里的速度差异是 IT 行业的一个核心 ...

  5. 五,pod控制器应用进阶

    目录 Pod 资源 标签 给资源打标签 标签选择器 Pod 生命周期 pod状态探测 livenessProbe 状态探测 livenessProbe exec 测试 livenessProbe ht ...

  6. js事件总汇

    Mouse 事件 描述onClick                     鼠标点击事件,多用在某个对象控制的范围内的鼠标点击 onDblClick                鼠标双击事件 on ...

  7. hdu4405 概率dp

    飞行棋游戏 问从0结束游戏的投色子次数期望是多少 设dp[i]表示i到n的期望,那么可以得到dp[i]=(dp[i+1]+dp[i+2]+dp[i+3]+dp[i+4]+dp[i+5]+dp[i+6] ...

  8. 清北学堂dp图论营游记day4

    依然zhx讲. 讲了概率与期望: 期望:事件结果的平均大小.记作E(x). E(x)=每种结果的大小与其概率的乘积的和. 例如,记掷一枚骰子的点数为x E(x)=1*(1/6)+2*(1/6)+3*( ...

  9. VMware Tools按钮变灰色,无法安装的解决方法

    参考博客: https://blog.csdn.net/weixin_30639719/article/details/94846851 https://jingyan.baidu.com/artic ...

  10. **JAVA参数传递方式 (按值传递与引用传递区别)

    https://blog.csdn.net/q5706503/article/details/82910428public class TestMain { public static void ma ...