当前位置:网站首页>Basic use of Go Context
Basic use of Go Context
2022-08-10 14:53:00 【EthanLeo】
Go Context的基本使用
This article is mainly used to introducegolang里面context的使用,Because it was not clear beforecontext的用法,以及context的一些基本特性.
Context的使用场景
ContextThe function can be reflected from two aspects:
Send a termination signal to the method Pass some common data to multiple methods
Why do you need to cancel the operation(终止信号)
简单来说,We need some termination signals,to tell our program to stop doing some unnecessary work.
用一个简单的例子来说明:

Send the request from the client to the program processing and then to the database,The normal process is shown in the figure below

But when the client sends a request,If the link is broken,Then under normal circumstances, the subsequent database query operation should be stopped,If there is no abort signal then the program will continue to execute,But the normal situation is to terminate the continued operation

So we know why the termination signal is needed
Go中ContextTerminate signaling mode
在goThere are two aspects to implementing the termination signal
Listen for termination events Post a termination event
Listen for termination events
Context提供了一个Done()的方法,该方法会返回一个channel,Every time the context sends a cancel event,Both send an empty onestruct{}into this pipeline,So in order to listen to the cancellation event,我们需要等待 <-ctx.Done()The semaphore passed.
func TestListeningCancel(t *testing.T) {
// 测试方法
// 浏览器打开localhost:8000
// It will return after two secondsrequest processed
// If you disconnect immediately after sending the request then ctx.Done() 能够收到信号 执行中断
http.ListenAndServe(":8000", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
fmt.Fprint(os.Stdout, "processing request\n")
select {
case <-time.After(2 * time.Second):
// 2If a signal is received in seconds
// Indicates that the request was executed
w.Write([]byte("request processed"))
case <-ctx.Done():
// 如果请求被取消 The output request was canceled
fmt.Fprint(os.Stderr, "request cancelled")
}
}))
}
Send a termination event
If you have an operation to be cancelled,Then you need to send a cancel event through the context
我们可以通过ContextBuilt-in methods in the packageWithCancel(),该方法会返回一个context和一个function
ctx,fn :=context.WithCancel()
// This method assumes that an operation fails
func Operation1(ctx context.Context)error{
time.Sleep(100 *time.Millisecond)
return errors.New("failed")
}
func Operation2(ctx context.Context){
select {
case <-time.After(500*time.Millisecond):
fmt.Println("done")
case <-ctx.Done():
fmt.Println("halted operation2")
}
}
func TestEmittingCancel(t *testing.T){
// 创建一个新的context
ctx := context.Background()
// Created by a primitivectx Wrap it up as a new one,with a cancel methodctx
ctx, cancel := context.WithCancel(ctx)
// Perform the above two operations ,Let an operation be in onego routine中
go func() {
err := Operation1(ctx)
if err!=nil{
cancel()
}
}()
// 执行2The same is used when operatingctx
Operation2(ctx)
}
This example is a demonstration,goWhen a coroutine sends a cancel signal,监听相同contextThe thread can also receive the signal,并执行操作
超时取消
contextThe package also provides a timeout cancellation methodcontext.WithTimeout
,This method will automatically send a cancel signal after the countdown is over
func TestCancelWithTimeout(t *testing.T){
// 创建一个空ctx
ctx := context.Background()
// 设置超时时间
cxt, _ := context.WithTimeout(ctx, 1*time.Millisecond)
// 创建一个请求 访问谷歌
req, _ := http.NewRequest(http.MethodGet, "http://baidu.com", nil)
// will have a cancel methodctxassociated with the request
req = req.WithContext(cxt)
client := &http.Client{}
res, err := client.Do(req)
if err!=nil{
fmt.Println("Request failed:", err)
return
}
fmt.Println("Response received, status code:", res.StatusCode)
}
Context Values
When there are multiple operations that need to use the same onevalue的时候,context也提供了对应的方法,Multiple execution methods can get the value,Passing by value using such a method guarantees the operation of changing the value是线程安全的
const keyID = "id"
func TestContextWithValue(t *testing.T) {
rand.Seed(time.Now().Unix())
ctx := context.WithValue(context.Background(), keyID, rand.Int())
operation1(ctx)
}
func operation1(ctx context.Context) {
log.Println("operation1 for id:", ctx.Value(keyID), " completed")
operation2(ctx)
}
func operation2(ctx context.Context) {
log.Println("operation2 for id:", ctx.Value(keyID), " completed")
}
以上就是context的一些基本操作,The follow-up sequence also needs to go into in-depth research
边栏推荐
猜你喜欢
随机推荐
【POI 2008, BLO】Cut Point
PyTorch multi-machine multi-card training: DDP combat and skills
MQTT服务器搭建
@RequestBody的使用[通俗易懂]
sql语句 异常 Err] 1064 – You have an error in your SQL syntax; check the manual that corresponds to your
DB2查询2个时间段之间的所有月份,DB2查询2个时间段之间的所有日期
蓝帽杯半决赛火炬木wp
2011年下半年 系统架构设计师 下午试卷 II
重要通知 | “移动云杯”算力网络应用创新大赛初赛延期!!
丁香园
C#实现访问OPC UA服务器
A method that can make large data clustering 2000 times faster
领域驱动模型设计与微服务架构落地-从项目去剖析领域驱动
leetcode 739. Daily Temperatures Daily Temperatures (Moderate)
“Oracle 封禁了我的账户”
vue 怎么清除tab 切换缓存问题 ?
兆骑科创创业赛事活动发布平台,创业赛事,项目路演
【剑指offer】---数组中的重复数字
波士顿房价预测
systemui屏蔽通知栏