ex1

package main

import (
"fmt"
) // 最佳context 实践
// Context 目标是实现各个goroutine能及时终止退出。 func main() {
// Basic ipfsnode setup
a := 10
fmt.Println("hhha")
fmt.Println(a)
}

ex2

package main

import "fmt"

// 打印输出, 发送数据到通道
func printHello(ch chan int) {
fmt.Println("Hello from printHello")
// 发送一个数据到通道
ch <- 2
} func main() {
/*
使用make函数,创建一个通道。
通道是可以带缓冲的, 如果你指定了长度。如ch := make(chan int, 2) channel可分为三种类型:
只读channel:只能读channel里面数据,不可写入
只写channel:只能写数据,不可读
一般channel:可读可写
*/
ch := make(chan int)
//内联goroutine. 定义一个函数,直接go调用.
//结束时,往通道发一个数据作为信号
go func(){
fmt.Println("Hello inline")
//send a value on channel
ch <- 1
}()
//调用一个函数作为 goroutine
go printHello(ch)
fmt.Println("Hello from main") //首先从通道中取出一个数据, 并赋值给变量,并打印出来
i := <- ch
fmt.Println("Recieved ",i)
//从通道获取第二个数据
// 如果不需要它, 可以不赋值给变量
<- ch
}

ex3

/*
context(上下文): 可以理解为timeout(超时), deadline(终止时间线), 或者一个channel(通道)来指示goroutine停止工作并退出
比如,在系统中, 当调用其它网站的接口时,通常速度比较慢, 但是你又依赖它的及时返回, 所以并不打算把这个进行备份请求。 通常会设置一个超时。
*/ /* 结构如下
// deadline终止时间线, cancelation 取消信号, and request-scoped 请求范围值
// 多个goroutines同时使用,是安全的
type Context interface {
// Done 方法在Context被取消或超时时返回一个close的channel,close的channel可以作为广播通知,告诉给context相关的函数要停止当前工作然后返回。
// 当一个父operation启动一个goroutine用于子operation,这些子operation不能够取消父operation。下面描述的WithCancel函数提供一种方式可以取消新创建的Context.
// Context可以安全的被多个goroutine使用。开发者可以把一个Context传递给任意多个goroutine然后cancel这个context的时候就能够通知到所有的goroutine。
Done() <-chan struct{} // Err方法返回context为什么被取消。
Err() error // Deadline返回context何时会超时。
Deadline() (deadline time.Time, ok bool) // Value返回context相关的数据。
Value(key interface{}) interface{}
}
*/
// 创建context上下文 // 1. context.Backgrond() ctx Context
// BackGound是所有Context的root,不能够被cancel。
// 这个函数返回一个空的上下文, 这个仅在高层使用(如在main 或者 顶级请求) /* 2. WithCancel返回一个继承的Context,这个Context在父Context的Done被关闭时关闭自己的Done通道,或者在自己被Cancel的时候关闭自己的Done。
WithCancel同时还返回一个取消函数cancel,这个cancel用于取消当前的Context。
*/ package main import (
"context"
"log"
"os"
"time"
) var logg *log.Logger func someHandler() {
ctx, cancel := context.WithCancel(context.Background())
go doStuff(ctx) //10秒后取消doStuff
time.Sleep(10 * time.Second)
cancel() } //每1秒work一下,同时会判断ctx是否被取消了,如果是就退出
func doStuff(ctx context.Context) {
for {
time.Sleep(1 * time.Second)
select {
case <-ctx.Done():
logg.Printf("done")
return
default:
logg.Printf("work")
}
}
} func main() {
logg = log.New(os.Stdout, "", log.Ltime)
someHandler()
logg.Printf("down")
}

ex4

/*
context(上下文):
withDeadline withTimeout
*/ /* 结构如下
// deadline终止时间线, cancelation 取消信号, and request-scoped 请求范围值
// 多个goroutines同时使用,是安全的
type Context interface {
// Done 方法在Context被取消或超时时返回一个close的channel,close的channel可以作为广播通知,告诉给context相关的函数要停止当前工作然后返回。
// 当一个父operation启动一个goroutine用于子operation,这些子operation不能够取消父operation。下面描述的WithCancel函数提供一种方式可以取消新创建的Context.
// Context可以安全的被多个goroutine使用。开发者可以把一个Context传递给任意多个goroutine然后cancel这个context的时候就能够通知到所有的goroutine。
Done() <-chan struct{} // Err方法返回context为什么被取消。
Err() error // Deadline返回context何时会超时。
Deadline() (deadline time.Time, ok bool) // Value返回context相关的数据。
Value(key interface{}) interface{}
}
*/
package main import (
"context"
"log"
"os"
"time"
) var logg *log.Logger //每1秒work一下,同时会判断ctx是否被取消了,如果是就退出
func doStuff(ctx context.Context) {
for {
time.Sleep(1 * time.Second)
select {
case <-ctx.Done():
logg.Printf("done")
return
default:
logg.Printf("work")
}
}
}
func timeoutHandler() {
// 这里在上下文中加入了超时限制, 超时和取消,取其短。
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(2 * time.Second))
go doStuff(ctx)
time.Sleep(10 * time.Second)
cancel()
} func main() {
logg = log.New(os.Stdout, "", log.Ltime)
timeoutHandler()
logg.Printf("end")
}

ex5

/*
context(上下文):
withDeadline withTimeout
*/ /* 结构如下
// deadline终止时间线, cancelation 取消信号, and request-scoped 请求范围值
// 多个goroutines同时使用,是安全的
type Context interface {
// Done 方法在Context被取消或超时时返回一个close的channel,close的channel可以作为广播通知,告诉给context相关的函数要停止当前工作然后返回。
// 当一个父operation启动一个goroutine用于子operation,这些子operation不能够取消父operation。下面描述的WithCancel函数提供一种方式可以取消新创建的Context.
// Context可以安全的被多个goroutine使用。开发者可以把一个Context传递给任意多个goroutine然后cancel这个context的时候就能够通知到所有的goroutine。
Done() <-chan struct{} // Err方法返回context为什么被取消。
Err() error // Deadline返回context何时会超时。
Deadline() (deadline time.Time, ok bool) // Value返回context相关的数据。
Value(key interface{}) interface{}
}
*/
package main import (
"context"
"log"
"os"
"time"
) var logg *log.Logger //每1秒work一下,同时会判断ctx是否被取消了,如果是就退出
func doStuff(ctx context.Context) {
for {
time.Sleep(1 * time.Second)
select {
case <-ctx.Done():
logg.Printf("done")
return
default:
logg.Printf("work")
}
}
}
func doTimeOutStuff(ctx context.Context) {
for {
time.Sleep(1 * time.Second) if deadline, ok := ctx.Deadline(); ok { //设置了deadl
logg.Printf("deadline set")
if time.Now().After(deadline) {
logg.Printf(ctx.Err().Error())
return
} } select {
case <-ctx.Done():
logg.Printf("done")
return
default:
logg.Printf("work")
}
}
} func timeoutHandler() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
// ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))
go doTimeOutStuff(ctx)
// go doStuff(ctx) time.Sleep(10 * time.Second) cancel() } func main() {
logg = log.New(os.Stdout, "", log.Ltime)
timeoutHandler()
logg.Printf("end")
}

ex6

/*
context(上下文):
withValue 附加一些(不可变)数据, 供派生goroutine查询用
*/ package main import (
"context"
"log"
"os"
"time"
) const (
GOLABLE_KEY = "test123"
) func main() {
//父context控制子context
controlAllConrrent()
} func controlAllConrrent() { logg := log.New(os.Stdout, "", log.Ltime)
handleSome()
logg.Println("over ")
} //父协程
func handleSome() {
//ctx, cancelFunc := context.WithCancel(context.Background())
//ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*2)
ctx, cancelFunc := context.WithDeadline(context.Background(), time.Now().Add(time.Second*2)) ctx = context.WithValue(ctx, GOLABLE_KEY, "1234") go workerFunc(ctx, "str1")
go workerFunc(ctx, "str2")
time.Sleep(time.Second * 3)
cancelFunc()
} //子协程
func workerFunc(ctx context.Context, showStr string) {
for {
time.Sleep(time.Second * 1)
select {
case <-ctx.Done():
log.Println("done")
return
default:
val123 := ctx.Value(GOLABLE_KEY).(string)
log.Println(val123, showStr)
}
}
}

golang context的更多相关文章

  1. Golang Context 详细介绍

    Golang context 本文包含对context实现上的分析和使用方式,分析部分源码讲解比价多,可能会比较枯燥,读者可以直接跳过去阅读使用部分. ps: 作者本着开源分享的精神撰写本篇文章,如果 ...

  2. Golang Context 包详解

    Golang Context 包详解 0. 引言 在 Go 语言编写的服务器程序中,服务器通常要为每个 HTTP 请求创建一个 goroutine 以并发地处理业务.同时,这个 goroutine 也 ...

  3. 带小伙伴手写 golang context

    前言 - context 源码 可以先了解官方 context.go 轮廓. 这里捎带保存一份当前 context 版本备份. // Copyright 2014 The Go Authors. Al ...

  4. golang context学习记录1

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

  5. Golang Context 的原理与实战

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

  6. 【GoLang】golang context channel 详解

    代码示例: package main import ( "fmt" "time" "golang.org/x/net/context" ) ...

  7. Golang context包解读

    Context 通常被译作 上下文 ,一般理解为程序单元的一个运行状态.现场.快照,而翻译中 上下 又很好地诠释了其本质,上下上下则是存在上下层的传递, 上 会把内容传递给 下 . 在Go语言中,程序 ...

  8. golang context 剖析 1.7.4 版本

    1. 内部结构之 - timerCtx . type timerCtx struct { cancelCtx timer *time.Timer // Under cancelCtx.mu. dead ...

  9. golang Context for goroutines

    概要 goroutine 的控制 取消控制 超时控制 goroutine 之间的传值 总结 概要 golang 的提供的 channel 机制是基于 CSP(Communicating Sequenc ...

  10. golang context包

    go context标准库 context包在Go1.7版本时加入到标准库中.其设计目标是给Golang提供一个标准接口来给其他任务发送取消信号和传递数据.其具体作用为: 可以通过context发送取 ...

随机推荐

  1. 2018项目总结(vue+apicloud)

    一.关于字数统计的问题 在使用textarea时常会对textarea中的文字数目进行统计,一般来说,可以使用onkeyup事件来解决问题. <textarea id="descrip ...

  2. idea函数被调用

    打开一个复杂的程序或者项目进行分析的时候,我们就需要知道一个方法在哪里被调用,用于迅速厘清代码逻辑.操作如下:选中函数,右键,点击Find Usages. 如图: 操作简单,但右键还是没有快捷键方便. ...

  3. Centos7中网络及设备相关配置

    centos7中,不再赞成使用ifconfig工具,取而代之的是nmcli工具,服务管理也是以systemctl工具取代了service,这些之前版本的工具虽然在centos7中还可以继续使用,只是出 ...

  4. 一、linux概述

    1. 学习Linux之前先了解Unix Unix是一个强大的多用户.多任务操作系统.于1969年在AT&T的贝尔实验室开发.UNIX的商标权由国际开放标准组织(The Open Group) ...

  5. Python读取xlsx文件

    Python读取xlsx文件 脚本如下: from openpyxl import load_workbook workbook = load_workbook(u'/tmp/test.xlsx') ...

  6. Python3 open函数

    Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError. 注意:使用 open() 方法一定要保证关闭 ...

  7. 展示金额的方法(1元-->1.00元)

    public static String showMoneyByTwoDecimal(String account) { DecimalFormat doubleFormatter = new Dec ...

  8. 5、AngularJS 直接绑定显示html ($sce、$sanitize服务)

    1.直接使用$sce服务(angularjs中:$sce.trustAsHtml($scope.snippet).html:ng-bind-html="snippet") 以下代码 ...

  9. 数据库学习二三事儿(不打代码永远get不到的东西)

    针对聚合函数: 1.在自己打的过程中,发现如果select里面有一个列名有被聚合函数用到,比如: 这里的count和Sum_salary均邮局和函数,照理来说branchNo是不能搞进去的,但是它被g ...

  10. DevExpress v18.2新版亮点——DevExtreme篇(五)

    行业领先的.NET界面控件2018年第二次重大更新——DevExpress v18.2日前正式发布,本站将以连载的形式为大家介绍新版本新功能.本文将介绍了DevExtreme Complete Sub ...