Go語(yǔ)言中的上下文(Context)是一種用于在 Goroutines 之間傳遞取消信號(hào)、截止時(shí)間和其他請(qǐng)求范圍值的標(biāo)準(zhǔn)方式。context
包提供了 Context
類(lèi)型和一些相關(guān)的函數(shù),用于在并發(fā)程序中有效地傳遞上下文信息。
在Go語(yǔ)言中,上下文通常用于以下場(chǎng)景:
- 請(qǐng)求的傳遞:當(dāng)一個(gè)請(qǐng)求從客戶端發(fā)送到服務(wù)器時(shí),可以使用上下文來(lái)攜帶與該請(qǐng)求相關(guān)的數(shù)據(jù)。這些數(shù)據(jù)可以是用戶的身份信息、請(qǐng)求的元數(shù)據(jù)或其他與請(qǐng)求相關(guān)的信息。通過(guò)將上下文傳遞給處理該請(qǐng)求的goroutine,可以確保在整個(gè)處理過(guò)程中訪問(wèn)這些數(shù)據(jù)。
- 取消操作:上下文可以用于取消正在進(jìn)行的操作。當(dāng)用戶或其他代碼發(fā)送取消信號(hào)時(shí),可以將該信號(hào)傳遞給正在執(zhí)行操作的goroutine。goroutine在接收到取消信號(hào)后,可以根據(jù)需要執(zhí)行清理操作并退出。
- 截止時(shí)間:有時(shí)候需要在一段時(shí)間后終止正在進(jìn)行的操作。通過(guò)將截止時(shí)間與上下文一起傳遞給goroutine,可以確保在超過(guò)截止時(shí)間后執(zhí)行適當(dāng)?shù)那謇聿僮鞑⑼顺觥?/li>
- 跨多個(gè)服務(wù)通信:當(dāng)在分布式系統(tǒng)中使用Go語(yǔ)言時(shí),上下文可以用于跨不同的服務(wù)之間傳遞請(qǐng)求數(shù)據(jù)、取消信號(hào)和截止時(shí)間。通過(guò)使用上下文,可以確保在整個(gè)系統(tǒng)中的各個(gè)服務(wù)之間保持一致的上下文和請(qǐng)求生命周期管理。
通過(guò)使用上下文,可以有效地在 Goroutines 之間傳遞取消信號(hào)、截止時(shí)間和請(qǐng)求范圍的值,從而更好地控制并發(fā)程序的行為。
1. context.Context 接口
Context
接口定義了在 Goroutines 之間傳遞的上下文的基本方法:
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key interface{}) interface{}
}
-
Deadline():返回上下文的截止時(shí)間。如果存在截止時(shí)間,
ok
為true
,否則為false
。 - Done():返回一個(gè)通道,該通道關(guān)閉時(shí)表示上下文被取消或者超過(guò)了截止時(shí)間。
-
Err():返回上下文取消的原因。如果上下文沒(méi)有被取消,則返回
nil
。 -
Value(key):返回與給定
key
關(guān)聯(lián)的值。這允許在上下文中傳遞請(qǐng)求范圍的數(shù)據(jù)。
2. 創(chuàng)建上下文
在 Go 中,上下文可以通過(guò) context.Background()
創(chuàng)建,它是一個(gè)無(wú)值的上下文,通常用作根上下文。根上下文不能被取消,也不能傳遞截止時(shí)間。
ctx := context.Background()
可以使用 context.WithCancel
、context.WithTimeout
、context.WithDeadline
和 context.WithValue
等函數(shù)創(chuàng)建派生上下文,這些函數(shù)分別用于創(chuàng)建帶有取消、超時(shí)、截止時(shí)間和值的上下文。
// 創(chuàng)建一個(gè)帶有取消功能的上下文
ctx, cancel := context.WithCancel(context.Background())
// 創(chuàng)建一個(gè)帶有超時(shí)的上下文
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
// 創(chuàng)建一個(gè)帶有截止時(shí)間的上下文
deadline := time.Now().Add(2 * time.Second)
ctx, cancel := context.WithDeadline(context.Background(), deadline)
// 創(chuàng)建一個(gè)帶有值的上下文
key := "key"
value := "value"
ctx := context.WithValue(context.Background(), key, value)
3. 傳遞上下文
在 Go 中,通過(guò)函數(shù)參數(shù)將上下文傳遞給調(diào)用的函數(shù),從而使調(diào)用的函數(shù)能夠感知上下文的取消或超時(shí)。例如:
func myFunction(ctx context.Context) {
// 在這里使用 ctx 處理邏輯
select {
case <-ctx.Done():
// 上下文被取消,執(zhí)行清理工作
fmt.Println("Context canceled")
return
default:
// 繼續(xù)正常的邏輯
fmt.Println("Doing some work")
}
}
func main() {
// 創(chuàng)建帶有取消功能的上下文
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// 啟動(dòng) Goroutine,傳遞上下文
go myFunction(ctx)
// 主 Goroutine 執(zhí)行一些工作
time.Sleep(2 * time.Second)
}
4. 上下文的取消
調(diào)用 cancel()
函數(shù)會(huì)取消與上下文相關(guān)的 Goroutines。一旦上下文被取消,與之關(guān)聯(lián)的所有 Goroutines 都會(huì)收到取消信號(hào)。
ctx, cancel := context.WithCancel(context.Background())
// 啟動(dòng) Goroutine,傳遞上下文
go func(ctx context.Context) {
select {
case <-ctx.Done():
// 上下文被取消,執(zhí)行清理工作
fmt.Println("Context canceled")
return
}
}(ctx)
// 取消上下文
cancel()
5. 上下文的超時(shí)和截止時(shí)間
使用 context.WithTimeout
或 context.WithDeadline
函數(shù)可以設(shè)置上下文的超時(shí)或截止時(shí)間。當(dāng)超過(guò)指定的時(shí)間后,上下文會(huì)自動(dòng)取消。
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
// 啟動(dòng) Goroutine,傳遞上下文
go func(ctx context.Context) {
select {
case <-ctx.Done():
// 上下文超時(shí),執(zhí)行清理工作
fmt.Println("Context timeout")
return
}
}(ctx)
// 主 Goroutine 執(zhí)行一些工作
time.Sleep(3 * time.Second)
6. 上下文值
context.WithValue
函數(shù)可以用于在上下文中傳遞請(qǐng)求范圍的值。這些值可以通過(guò) context.Value
方法在上下文中檢索。
ctx := context.WithValue(context.Background(), "user", "john_doe")
// 從上下文中獲取值
value := ctx.Value("user")
fmt.Println(value) // 輸出: john_doe
7. 上下文的鏈?zhǔn)秸{(diào)用
可以通過(guò)鏈?zhǔn)秸{(diào)用的方式,將多個(gè)上下文進(jìn)行組合,形成一個(gè)父子關(guān)系的上下文鏈。
parentCtx := context.Background()
ctx1, cancel1 := context.WithTimeout(parentCtx, 2*time.Second)
defer cancel1()
ctx2, cancel2 := context.WithCancel(ctx1)
defer cancel2()
上述的 ctx2
是 ctx1
的子上下文,當(dāng) ctx1
超時(shí)或被取消時(shí),ctx2
也會(huì)相應(yīng)地被取消。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-746288.html

聲明:本作品采用署名-非商業(yè)性使用-相同方式共享 4.0 國(guó)際 (CC BY-NC-SA 4.0)進(jìn)行許可,使用時(shí)請(qǐng)注明出處。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 戀水無(wú)意文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-746288.html
到了這里,關(guān)于go 上下文:context.Context的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!