golang context
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的更多相关文章
- Golang Context 详细介绍
Golang context 本文包含对context实现上的分析和使用方式,分析部分源码讲解比价多,可能会比较枯燥,读者可以直接跳过去阅读使用部分. ps: 作者本着开源分享的精神撰写本篇文章,如果 ...
- Golang Context 包详解
Golang Context 包详解 0. 引言 在 Go 语言编写的服务器程序中,服务器通常要为每个 HTTP 请求创建一个 goroutine 以并发地处理业务.同时,这个 goroutine 也 ...
- 带小伙伴手写 golang context
前言 - context 源码 可以先了解官方 context.go 轮廓. 这里捎带保存一份当前 context 版本备份. // Copyright 2014 The Go Authors. Al ...
- golang context学习记录1
1.前言 一个请求,可能涉及多个API调用,多个goroutine,如何在多个API 之间,以及多个goroutine之间协作和传递信息,就是一个问题. 比如一个网络请求Request,需要开启一些g ...
- Golang Context 的原理与实战
本文让我们一起来学习 golang Context 的使用和标准库中的Context的实现. golang context 包 一开始只是 Google 内部使用的一个 Golang 包,在 Gola ...
- 【GoLang】golang context channel 详解
代码示例: package main import ( "fmt" "time" "golang.org/x/net/context" ) ...
- Golang context包解读
Context 通常被译作 上下文 ,一般理解为程序单元的一个运行状态.现场.快照,而翻译中 上下 又很好地诠释了其本质,上下上下则是存在上下层的传递, 上 会把内容传递给 下 . 在Go语言中,程序 ...
- golang context 剖析 1.7.4 版本
1. 内部结构之 - timerCtx . type timerCtx struct { cancelCtx timer *time.Timer // Under cancelCtx.mu. dead ...
- golang Context for goroutines
概要 goroutine 的控制 取消控制 超时控制 goroutine 之间的传值 总结 概要 golang 的提供的 channel 机制是基于 CSP(Communicating Sequenc ...
- golang context包
go context标准库 context包在Go1.7版本时加入到标准库中.其设计目标是给Golang提供一个标准接口来给其他任务发送取消信号和传递数据.其具体作用为: 可以通过context发送取 ...
随机推荐
- 4、static
static (静态的),用来修饰成员. 一.特点: 1.被修饰的方法或变量随着类的加载而加载 2.优先于对象存在 3.被所有的对象共享 4.除了可以被对象调用还可以被类名直接调用 二.类变量.成员变 ...
- 当你的layui表格要做全选+删除功能【兼容ie8】
<!-- 全选 --> <div class="choose"> <input type="checkbox" id=" ...
- Vue.js安装使用教程
一.说明 上大学前,请的都是前端JavaScript.后端ASP/PHP/JSP.前后端代码混杂:上大学时,请的都是前端Jquery.后端SSH.前后端代码分离通过模板关联:大学出来后,请的都是前端三 ...
- Jedis路由key的算法剥离
在Redis集群中,会有很多个分片,如果此时利用Jedis来操作此Redis集群,那么他会把数据路由到不到的分片上.而且如果动态的往集群中增加分片,也不会影响Jedis的功能.究竟是怎么做到的呢? 由 ...
- 关于WinSock编程的多线程控制
1引言Windows Sockets规范以U.C. Berkeley大学BSD UNIX中流行的Socket接口为范例定义了一套Microsoft Windows下网络编程接口.它不仅包含了人们所熟悉 ...
- Spring、SpringMVC区别
1. 为什么使用Spring ? 1). 方便解耦,简化开发 通过Spring提供的IoC容器,可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合. 2). AOP编程的 ...
- 文件操作fopen
这块所谓的"文件操作"就是把文件的内容读进程序,然后根据具体的格式进行解析,或者是显示,或者是修改. 也就是把一个文件加载到程序里面,然后对其进行修改. 文件操作就三步(固定的三步 ...
- 从excel表中生成批量SQL,将数据录入到数据库中
excel表格中有许多数据,需要将数据导入数据库中,又不能一个一个手工录入,可以生成SQL,来批量操作. 1.首先在第二行的H列,插入函数:=CONCATENATE("INSERT ...
- 第十节 集合类Collection和Map
接口 Collection<E> (E)代表类型 集合类: 与数组的异同: 数组:数组虽然也可以存储对象,但长度是固定的:集合的长度是可变的,数组中可以存储基本数据类型,集合只能存储对象 ...
- Input标签_实现限制输入字符类型(只能输入特定类型字符)
... <input type="text" placeholder="密码" maxlength="20" onKeyPress=& ...