校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > golang中context的作用詳解

golang中context的作用詳解

熱門標簽:不封卡外呼系統 仙桃400電話辦理 地圖標注免費定制店 宿遷便宜外呼系統代理商 上海極信防封電銷卡價格 鄭州智能語音電銷機器人價格 重慶慶云企業400電話到哪申請 寧波語音外呼系統公司 湛江crm外呼系統排名

當一個goroutine可以啟動其他goroutine,而這些goroutine可以啟動其他goroutine,依此類推,則第一個goroutine應該能夠向所有其它goroutine發送取消信號。

上下文包的唯一目的是在goroutine之間執行取消信號,而不管它們如何生成。上下文的接口定義為:

type Context interface {
 Deadline() (deadline time.Time, ok bool)
 Done() - chan struct{}
 Err() error
 Value(key interface{}) interface{}
}
  • Deadline:第一個值是截止日期,此時上下文將自動觸發“取消”操作。第二個值是布爾值,true表示設置了截止日期,false表示未設置截止時間。如果沒有設置截止日期,則必須手動調用cancel函數來取消上下文。
  • Done:返回一個只讀通道(僅在取消后),鍵入struct {},當該通道可讀時,表示父上下文已經發起了取消請求,根據此信號,開發人員可以執行一些清除操作,退出goroutine
  • Err:返回取消上下文的原因
  • Value:返回綁定到上下文的值,它是一個鍵值對,因此您需要傳遞一個Key來獲取相應的值,此值是線程安全的

要創建上下文,必須指定父上下文。兩個內置上下文(背景和待辦事項)用作頂級父上下文:

var (
 background = new(emptyCtx)
 todo = new(emptyCtx)
)
func Background() Context {
 return background
}
func TODO() Context {
 return todo
}

背景,主要ü在主函數,初始化和測試代碼的sed,是樹結構中,根上下文,這是不能被取消的頂層語境。TODO,當您不知道要使用什么上下文時,可以使用它。它們本質上都是emptyCtx類型,都是不可取消的,沒有固定的期限,也沒有為Context賦任何值:鍵入emptyCtx int

type emptyCtx int
func (_ *emptyCtx) Deadline() (deadline time.Time, ok bool) {
 return
}
func (_ *emptyCtx) Done() - chan struct{} {
 return nil
}
func (_ *emptyCtx) Err() error {
 return nil
}
func (*emptyCtx) Value(key interface{}) interface{} {
 return nil
}

上下文包還具有幾個常用功能:func WithCancel(父上下文)(ctx上下文,取消CancelFunc)func WithDeadline(父上下文,截止時間.Time)(上下文,CancelFunc)func WithTimeout(父上下文,超時時間。持續時間)(上下文,CancelFunc)func WithValue(父上下文,鍵,val接口{})上下文

請注意,這些方法意味著可以一次繼承上下文以實現其他功能,例如,使用WithCancel函數傳入根上下文,它會創建一個子上下文,該子上下文具有取消上下文的附加功能,然后使用此方法將context(context01)作為父上下文,并將其作為第一個參數傳遞給WithDeadline函數,與子context(context01)相比,獲得子context(context02),它具有一個附加功能,可在之后自動取消上下文最后期限。

WithCancel

對于通道,盡管通道也可以通知許多嵌套的goroutine退出,但通道不是線程安全的,而上下文是線程安全的。

例如:

package main
import (
 "runtime"
 "fmt"
 "time"
 "context"
)
func monitor2(ch chan bool, index int) {
 for {
  select {
  case v := - ch:
   fmt.Printf("monitor2: %v, the received channel value is: %v, ending\n", index, v)
   return
  default:
   fmt.Printf("monitor2: %v in progress...\n", index)
   time.Sleep(2 * time.Second)
  }
 }
}
func monitor1(ch chan bool, index int) {
 for {
  go monitor2(ch, index)
  select {
  case v := - ch:
   // this branch is only reached when the ch channel is closed, or when data is sent(either true or false)
   fmt.Printf("monitor1: %v, the received channel value is: %v, ending\n", index, v)
   return
  default:
   fmt.Printf("monitor1: %v in progress...\n", index)
   time.Sleep(2 * time.Second)
  }
 }
}
func main() {
 var stopSingal chan bool = make(chan bool, 0)
 for i := 1; i = 5; i = i + 1 {
  go monitor1(stopSingal, i)
 }
 time.Sleep(1 * time.Second)
 // close all gourtines
 cancel()
 // waiting 10 seconds, if the screen does not display monitorX: xxxx in progress...>, all goroutines have been shut down
 time.Sleep(10 * time.Second)
 println(runtime.NumGoroutine())
 println("main program exit!!!!")
}

執行的結果是:

monitor1: 5 in progress...
monitor2: 5 in progress...
monitor1: 2 in progress...
monitor2: 2 in progress...
monitor2: 1 in progress...
monitor1: 1 in progress...
monitor1: 4 in progress...
monitor1: 3 in progress...
monitor2: 4 in progress...
monitor2: 3 in progress...
monitor1: 4, the received channel value is: false, ending
monitor1: 3, the received channel value is: false, ending
monitor2: 2, the received channel value is: false, ending
monitor2: 1, the received channel value is: false, ending
monitor1: 1, the received channel value is: false, ending
monitor2: 5, the received channel value is: false, ending
monitor2: 3, the received channel value is: false, ending
monitor2: 3, the received channel value is: false, ending
monitor2: 4, the received channel value is: false, ending
monitor2: 5, the received channel value is: false, ending
monitor2: 1, the received channel value is: false, ending
monitor1: 5, the received channel value is: false, ending
monitor1: 2, the received channel value is: false, ending
monitor2: 2, the received channel value is: false, ending
monitor2: 4, the received channel value is: false, ending
1
main program exit!!!!

這里使用一個通道向所有goroutine發送結束通知,但是這里的情況相對簡單,如果在一個復雜的項目中,假設多個goroutine有某種錯誤并重復執行,則可以重復關閉或關閉該通道通道,然后向其寫入值,從而觸發運行時恐慌。這就是為什么我們使用上下文來避免這些問題的原因,以WithCancel為例:

package main
import (
 "runtime"
 "fmt"
 "time"
 "context"
)
func monitor2(ctx context.Context, number int) {
 for {
  select {
  case v := - ctx.Done():
   fmt.Printf("monitor: %v, the received channel value is: %v, ending\n", number,v)
   return
  default:
   fmt.Printf("monitor: %v in progress...\n", number)
   time.Sleep(2 * time.Second)
  }
 }
}
func monitor1(ctx context.Context, number int) {
 for {
  go monitor2(ctx, number)
  select {
  case v := - ctx.Done():
   // this branch is only reached when the ch channel is closed, or when data is sent(either true or false)
   fmt.Printf("monitor: %v, the received channel value is: %v, ending\n", number, v)
   return
  default:
   fmt.Printf("monitor: %v in progress...\n", number)
   time.Sleep(2 * time.Second)
  }
 }
}
func main() {
 var ctx context.Context = nil
 var cancel context.CancelFunc = nil
 ctx, cancel = context.WithCancel(context.Background())
 for i := 1; i = 5; i = i + 1 {
  go monitor1(ctx, i)
 }
 time.Sleep(1 * time.Second)
 // close all gourtines
 cancel()
 // waiting 10 seconds, if the screen does not display monitor: xxxx in progress>, all goroutines have been shut down
 time.Sleep(10 * time.Second)
 println(runtime.NumGoroutine())
 println("main program exit!!!!")
}

WithTimeout和WithDeadline

WithTimeout和WithDeadline在用法和功能上基本相同,它們都表示上下文將在一定時間后自動取消,唯一的區別可以從函數的定義中看出,傳遞給WithDeadline的第二個參數是類型time.Duration類型,它是一個相對時間,表示取消超時后的時間。例:

package main
import (
 "runtime"
 "fmt"
 "time"
 "context"
)
func monitor2(ctx context.Context, index int) {
 for {
  select {
  case v := - ctx.Done():
   fmt.Printf("monitor2: %v, the received channel value is: %v, ending\n", index, v)
   return
  default:
   fmt.Printf("monitor2: %v in progress...\n", index)
   time.Sleep(2 * time.Second)
  }
 }
}
func monitor1(ctx context.Context, index int) {
 for {
  go monitor2(ctx, index)
  select {
  case v := - ctx.Done():
   // this branch is only reached when the ch channel is closed, or when data is sent(either true or false)
   fmt.Printf("monitor1: %v, the received channel value is: %v, ending\n", index, v)
   return
  default:
   fmt.Printf("monitor1: %v in progress...\n", index)
   time.Sleep(2 * time.Second)
  }
 }
}
func main() {
 var ctx01 context.Context = nil
 var ctx02 context.Context = nil
 var cancel context.CancelFunc = nil
 ctx01, cancel = context.WithCancel(context.Background())
 ctx02, cancel = context.WithDeadline(ctx01, time.Now().Add(1 * time.Second)) // If it's WithTimeout, just change this line to "ctx02, cancel = context.WithTimeout(ctx01, 1 * time.Second)"
 defer cancel()
 for i := 1; i = 5; i = i + 1 {
  go monitor1(ctx02, i)
 }
 time.Sleep(5 * time.Second)
 if ctx02.Err() != nil {
  fmt.Println("the cause of cancel is: ", ctx02.Err())
 }
 println(runtime.NumGoroutine())
 println("main program exit!!!!")
}

WithValue

一些必需的元數據也可以通過上下文傳遞,該上下文將附加到上下文中以供使用。元數據作為鍵值傳遞,但請注意,鍵必須具有可比性,并且值必須是線程安全的。

package main
import (
 "runtime"
 "fmt"
 "time"
 "context"
)
func monitor(ctx context.Context, index int) {
 for {
  select {
  case - ctx.Done():
   // this branch is only reached when the ch channel is closed, or when data is sent(either true or false)
   fmt.Printf("monitor %v, end of monitoring. \n", index)
   return
  default:
   var value interface{} = ctx.Value("Nets")
   fmt.Printf("monitor %v, is monitoring %v\n", index, value)
   time.Sleep(2 * time.Second)
  }
 }
}
func main() {
 var ctx01 context.Context = nil
 var ctx02 context.Context = nil
 var cancel context.CancelFunc = nil
 ctx01, cancel = context.WithCancel(context.Background())
 ctx02, cancel = context.WithTimeout(ctx01, 1 * time.Second)
 var ctx03 context.Context = context.WithValue(ctx02, "Nets", "Champion") // key: "Nets", value: "Champion"

 defer cancel()
 for i := 1; i = 5; i = i + 1 {
  go monitor(ctx03, i)
 }
 time.Sleep(5 * time.Second)
 if ctx02.Err() != nil {
  fmt.Println("the cause of cancel is: ", ctx02.Err())
 }
 println(runtime.NumGoroutine())
 println("main program exit!!!!")
}

關于上下文,還有一些注意事項:不要將Context存儲在結構類型中,而是將Context明確傳遞給需要它的每個函數,并且Context應該是第一個參數。

即使函數允許,也不要傳遞nil Context,或者如果您不確定要使用哪個Context,請傳遞context。不要將可能作為函數參數傳遞給上下文值的變量傳遞。

到此這篇關于golang中context的作用的文章就介紹到這了,更多相關golang中context的作用內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • GoLang之使用Context控制請求超時的實現
  • golang通過context控制并發的應用場景實現
  • GOLANG使用Context實現傳值、超時和取消的方法
  • GOLANG使用Context管理關聯goroutine的方法
  • 深入Golang之context的用法詳解

標簽:安康 儋州 電子產品 青海 物業服務 海南 遼寧 西雙版納

巨人網絡通訊聲明:本文標題《golang中context的作用詳解》,本文關鍵詞  golang,中,context,的,作用,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《golang中context的作用詳解》相關的同類信息!
  • 本頁收集關于golang中context的作用詳解的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    成人性生交大片免费看中文网站| 色婷婷激情久久| 色综合久久久久综合体桃花网| 91精品国产综合久久福利软件 | 日韩女优制服丝袜电影| 国产精品国产自产拍高清av | 欧美一区二区三区免费视频| 国产精品成人免费在线| 免费高清在线一区| 欧美羞羞免费网站| 中文字幕一区二区三区蜜月| 国产一区二区在线电影| 3atv一区二区三区| 亚洲在线一区二区三区| av综合在线播放| 国产色一区二区| 国产在线视频一区二区三区| 欧美日本免费一区二区三区| 亚洲女爱视频在线| zzijzzij亚洲日本少妇熟睡| 久久久久国产精品麻豆 | 日本欧美在线观看| 欧美日韩一级大片网址| 亚洲欧美精品午睡沙发| 成人污污视频在线观看| 国产无一区二区| 国产精品一区二区在线播放| 精品美女在线观看| 黄一区二区三区| 久久亚洲影视婷婷| 国产一区二区三区高清播放| 精品美女一区二区三区| 国内成+人亚洲+欧美+综合在线| 精品少妇一区二区三区在线视频| 亚洲成在人线在线播放| 一本一本久久a久久精品综合麻豆 一本一道波多野结衣一区二区 | 亚洲高清免费视频| 欧美高清性hdvideosex| 午夜免费欧美电影| 制服视频三区第一页精品| 日产国产高清一区二区三区 | 国产精品18久久久久久vr| 久久久久国产精品厨房| 成人一区在线观看| 最新中文字幕一区二区三区| 91传媒视频在线播放| 婷婷丁香激情综合| 精品久久久久久综合日本欧美| 国产麻豆日韩欧美久久| 国产精品伦一区二区三级视频| 一本色道**综合亚洲精品蜜桃冫 | 欧美一区二区三区在线电影 | 日本久久电影网| 日韩激情视频网站| 久久久久国产精品厨房| 色婷婷av一区二区三区大白胸| 一区二区成人在线| 日韩欧美电影一二三| 成人免费视频视频在线观看免费| 亚洲婷婷在线视频| 日韩一级片网址| 波波电影院一区二区三区| 亚洲国产成人av网| 国产人伦精品一区二区| 欧美在线一二三四区| 精品在线观看视频| 亚洲一区在线看| 国产亚洲欧美日韩日本| 欧美性猛交一区二区三区精品| 青青草精品视频| 国产精品卡一卡二卡三| 91麻豆精品国产91久久久更新时间| 国产精品中文欧美| 午夜久久久久久电影| 久久综合精品国产一区二区三区| 色噜噜狠狠成人中文综合 | 成人动漫中文字幕| 日本不卡一二三区黄网| 亚洲国产成人在线| 日韩一区二区三区电影在线观看 | 国产网站一区二区三区| 欧美精选一区二区| 99国产精品视频免费观看| 日韩高清不卡一区二区| 日韩一区在线看| 久久免费国产精品| 欧美色图一区二区三区| 成人亚洲一区二区一| 精品在线观看免费| 三级一区在线视频先锋| 亚洲综合色视频| 国产精品久久久久三级| |精品福利一区二区三区| 久久国产夜色精品鲁鲁99| 国产欧美日韩在线| 日韩一区二区精品葵司在线| 成人听书哪个软件好| 色综合网站在线| 依依成人精品视频| av日韩在线网站| 中文字幕一区日韩精品欧美| 成人美女在线观看| 亚洲精品国产无天堂网2021| 欧洲亚洲国产日韩| 成人性生交大片| 欧美在线免费视屏| 国产欧美在线观看一区| 免费在线观看成人| 夜夜嗨av一区二区三区网页 | 精油按摩中文字幕久久| 日韩不卡在线观看日韩不卡视频| 亚洲香肠在线观看| 亚洲午夜激情网站| 亚洲福利视频一区| 亚洲成人免费视| 亚洲一级二级在线| 亚洲成人中文在线| 亚洲一区二区三区在线播放| 亚洲人xxxx| 亚洲成a人v欧美综合天堂| 五月开心婷婷久久| 免费精品99久久国产综合精品| 免费人成在线不卡| 国产做a爰片久久毛片| 国产精品亚洲专一区二区三区 | 亚洲欧洲无码一区二区三区| 中文字幕一区日韩精品欧美| 亚洲猫色日本管| 一级特黄大欧美久久久| 性做久久久久久| 久久国产剧场电影| 成人少妇影院yyyy| 欧美在线你懂的| 日韩欧美一区二区三区在线| 久久九九国产精品| 国产精品高潮久久久久无| 亚洲一区在线电影| 久久超碰97中文字幕| av亚洲产国偷v产偷v自拍| 欧美主播一区二区三区美女| 欧美一区二区免费| 欧美激情中文字幕| 亚洲二区视频在线| 精品一区在线看| av在线这里只有精品| 欧美日韩精品福利| 久久老女人爱爱| 亚洲精品视频在线观看免费| 日本伊人精品一区二区三区观看方式| 精品制服美女久久| 欧美中文字幕亚洲一区二区va在线| 日韩区在线观看| 亚洲欧美一区二区视频| 免费久久精品视频| 色综合视频在线观看| 精品久久久三级丝袜| 樱花影视一区二区| 国产成人亚洲综合a∨婷婷图片| 欧美亚洲国产一区二区三区va | 91在线视频免费91| 欧美一区二区三区小说| 专区另类欧美日韩| 美女视频黄免费的久久 | 天天影视网天天综合色在线播放| 国产精品一区二区91| 在线成人av影院| 日韩一区欧美一区| 国产成人99久久亚洲综合精品| 精品视频免费看| 成人欧美一区二区三区黑人麻豆 | 亚洲男人天堂一区| 国产一区二区在线观看视频| 88在线观看91蜜桃国自产| 中文字幕日本乱码精品影院| 精品系列免费在线观看| 欧美精品国产精品| 一区二区三区国产精品| 99re这里只有精品首页| 中文字幕av一区二区三区| 麻豆精品在线观看| 91精品国产91热久久久做人人| 亚洲一区免费观看| 色妹子一区二区| 亚洲视频在线一区观看| 成人小视频在线| 久久精品一区二区三区四区| 久久99九九99精品| 日韩亚洲欧美在线观看| 日韩不卡免费视频| 制服丝袜亚洲精品中文字幕| 亚洲福利视频三区| 欧美日韩一卡二卡| 五月婷婷激情综合网| 欧美三级一区二区| 亚洲一区二区三区自拍| 欧美性猛交一区二区三区精品| 亚洲影视在线观看| 欧美日韩国产bt| 婷婷激情综合网| 3atv在线一区二区三区|