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. wcf在post请求时,关于string类型参数传入中文的处理

    一.方法默认只有一个参数 (1)BodyStyle = WebMessageBodyStyle.Bare [OperationContract][WebInvoke(Method = "PO ...

  2. NPM 报错--fs: re-evaluating native module sources is not supported. If you are using the graceful-fs module

    fs: re-evaluating native module sources is not supported. If you are using the graceful-fs module 解决 ...

  3. 八大排序算法——归并排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 归并排序就是递归得将原始数组递归对半分隔,直到不能再分(只剩下一个元素)后,开始从最小的数组向上归并排序 1.  向上归并排序的时候,需要一个暂存数组用来排序, 2.  将 ...

  4. 使用有序GUID:提升其在各数据库中作为主键时的性能

    原文出处:https://www.codeproject.com/articles/388157/guids-as-fast-primary-keys-under-multiple-database  ...

  5. 怎样用div做三角形

    20181204 用盒子模型做三角形的效果: <div></div> width:0px; height:0px; border:10px solid red; border- ...

  6. Android Studio之SVN打分支、切换分支及合并分支

    1.打分支: 右击项目--Subversion--Branch or Tag 点击OK,分支就创建成功了,接下来我们切换到分支v2 2.切换分支: 右击项目--Subversion--Update D ...

  7. 使用labelme制作自己的数据集

    # python3 conda create --name=labelme python=3.6 source activate labelme # conda install -c conda-fo ...

  8. SoapUI之cookie设置

    一.测试背景: 1)接口测试需要完成注册-->登录-->充值,使用soapui构建好测试用例.设置断言后,运行结果如下: 2)recharge接口运行失败,继续查看该接口具体发送的请求及返 ...

  9. lvs,nginx反向代理,虚拟主机

    LVS NAT 拓扑 client | | LVS | | ------------------- | | | RS1 RS2 RS3 地址规划如下 机器名称 ip配置 ip配置 备注信息 LVS 1 ...

  10. 学习poisson.c

    static char help[] = "A structured-grid Poisson problem with DMDA+KSP.\n\n"; #include < ...