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. 4、static

    static (静态的),用来修饰成员. 一.特点: 1.被修饰的方法或变量随着类的加载而加载 2.优先于对象存在 3.被所有的对象共享 4.除了可以被对象调用还可以被类名直接调用 二.类变量.成员变 ...

  2. 当你的layui表格要做全选+删除功能【兼容ie8】

    <!-- 全选 --> <div class="choose"> <input type="checkbox" id=" ...

  3. Vue.js安装使用教程

    一.说明 上大学前,请的都是前端JavaScript.后端ASP/PHP/JSP.前后端代码混杂:上大学时,请的都是前端Jquery.后端SSH.前后端代码分离通过模板关联:大学出来后,请的都是前端三 ...

  4. Jedis路由key的算法剥离

    在Redis集群中,会有很多个分片,如果此时利用Jedis来操作此Redis集群,那么他会把数据路由到不到的分片上.而且如果动态的往集群中增加分片,也不会影响Jedis的功能.究竟是怎么做到的呢? 由 ...

  5. 关于WinSock编程的多线程控制

    1引言Windows Sockets规范以U.C. Berkeley大学BSD UNIX中流行的Socket接口为范例定义了一套Microsoft Windows下网络编程接口.它不仅包含了人们所熟悉 ...

  6. Spring、SpringMVC区别

    1. 为什么使用Spring ? 1). 方便解耦,简化开发 通过Spring提供的IoC容器,可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合. 2). AOP编程的 ...

  7. 文件操作fopen

    这块所谓的"文件操作"就是把文件的内容读进程序,然后根据具体的格式进行解析,或者是显示,或者是修改. 也就是把一个文件加载到程序里面,然后对其进行修改. 文件操作就三步(固定的三步 ...

  8. 从excel表中生成批量SQL,将数据录入到数据库中

    excel表格中有许多数据,需要将数据导入数据库中,又不能一个一个手工录入,可以生成SQL,来批量操作.     1.首先在第二行的H列,插入函数:=CONCATENATE("INSERT ...

  9. 第十节 集合类Collection和Map

    接口 Collection<E>  (E)代表类型 集合类: 与数组的异同: 数组:数组虽然也可以存储对象,但长度是固定的:集合的长度是可变的,数组中可以存储基本数据类型,集合只能存储对象 ...

  10. Input标签_实现限制输入字符类型(只能输入特定类型字符)

    ... <input type="text" placeholder="密码" maxlength="20" onKeyPress=& ...