国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

你應該掌握的 Go 高級并發模式:計時器

開發 前端
如果你認為結合 Goroutines 去處理時間和計數器很簡單的話,那你就錯了,這里有提到的一些與 time.Timer 相關的問題或 bug

 [[286701]]

前言

如果你認為結合 Goroutines 去處理時間和計數器很簡單的話,那你就錯了,這里有提到的一些與 time.Timer 相關的問題或 bug:

  • time: Timer.Reset is not possible to use correctly #14038[1]
  • time: Timer.C can still trigger even after Timer.Reset is called #11513[2]
  • time: document proper usage of Timer.Stop #14383[3]

看完上面的鏈接內容后,如果你依然認為很簡單,那來看看下面的代碼,如下代碼會產生死鎖和競爭條件

 

  1. tm := time.NewTimer(1)tm.Reset(100 * time.Millisecond)<-tm.Cif !tm.Stop() {<-tm.C} 

死鎖代碼片段

 

  1. func toChanTimed(t *time.Timer, ch chan int) {t.Reset(1 * time.Second)defer func() {if !t.Stop() {<-t.C}}()select {case ch <- 42:case <-t.C:}} 

可能代碼比較難懂,下面對相關方法進行闡述。

time.Ticker

 

  1. type Ticker struct {C <-chan Time // The channel on which the ticks are delivered.} 

Ticker 簡單易用,但也有一些小問題

  • 如果 C 中已存在一條消息,則發送消息時將刪除所有未讀值。
  • 必須有停止操作:否則 GC 無法回收它
  • 設置 C 無用:消息仍將在原始的 channel 上發送。

time.Tick

time.Tick 是對 time.NewTicker 的封裝。最好不要使用該方法,除非你準備將 chan 作為返回結果并在程序的整個生命周期中繼續使用它。正如官方描述:

垃圾收集器無法恢復底層的 Ticker,出現 " 泄漏 ". 請謹慎使用,如有疑問請改用 Ticker。

time.After

這與 Tick 的概念基本相同,它是對 Timer 進行封裝。一旦計時器被觸發,它將被回收。請注意,計時器使用了緩存容量是 1 的通道,即使沒有接收者,它仍可以進行計數。如上所述,如果您關心性能且希望能夠取消計時,那么你不應該使用 After。

time.Timer ( 也稱為 time.WhatTheFork?!)

對于 Go 來說這是一個比較奇怪的 API :NewTicker(Duration) 返回了一個 *Timer 類型,該類型僅暴露一個定義為 chan 類型的變量 C ,這點非常奇怪。

通常在 Go 語言中允許導出的字段意味著用戶可以獲取或設置該字段,而此處設置變量 C 并沒有實際意義。相反:設置 C 并重置 Timer 并不會影響之前在 C 通道的消息傳遞。更糟糕的是:AfterFunc 返回的 Timer 根本不會使用到 C。

這樣看來,Timer 很奇怪,以下是 API 的概述:

 

  1. type Timer struct {C <-chan Time}func AfterFunc(d Duration, f func()) *Timerfunc NewTimer(d Duration) *Timerfunc (*Timer) Stop(bool)func (*Timer) Reset(d Duration) bool 

四個非常簡單的函數,其中兩個是構造函數,有可能出錯嗎?

time.AfterFunc

官方文檔:AfterFunc 持續時間超時后通過開 Goroutine 去調用 f 函數,返回一個 Timer 類型,以便通過 Stop 方法取消調用。

這么描述雖然沒有問題,但需要注意:當調用 Stop 方法時,如果返回 false ,則表示該函數已經執行且停止失敗。但并不意味著函數已經返回,你需要添加一些處理邏輯:

 

  1. done := make(chan struct{})f := func() {doStuff()close(done)}t := time.AfterFunc(1*time.Second, f)if !t.Stop() {<-done} 

這個在 Stop 文檔中有相關說明。

除此之外,返回的計時器不會被觸發,只能用于調用 Stop 方法。

 

  1. t := time.AfterFunc(1*time.Second, func() {fmt.Println("Time has passed!")})// This will deadlock.<-t.C 

此外,寫這篇文章的時候,重置計時器會在傳入重置函數的時間段過去后再次調用 f,但這種特性目前暫沒有文檔規范,未來可能會被改變。

time.NewTimer

官方文檔 : NewTimer 實例化 Timer 結構體,在持續時間 d 之后發送當前時間至通道內 .

這意味著沒有聲明它就無法構建有效的 Timer 類型結構體。如果你需要構建一個以便后續重復使用,可以用該方法進行實例化,或者使用如下代碼實現自主創建和停止計數器

 

  1. t := time.NewTimer(0)if !t.Stop() {<-t.C} 

你必須從 channel 中讀取數據。假如在 New 和 Stop 調用期間觸發了定時器,且 channel 存在未消費的數據, 則 C 會存在一個值。將導致后續讀取均是錯誤的。

(*time.Timer).Stop

Stop 方法會阻止計時器觸發。如果調用停止計時器的方法,則返回 true,如果計時器已超時或者已停止,則返回 false。

以上句子中的“或”非常重要。文檔中所以關于 Stop 的示例都顯示了以下代碼片段:

 

  1. if !t.Stop() {<-t.C} 

關鍵點在于 "or" 它意味著有效 0 次或 1 次。對已消費完通道數據和在此期間未調用 Reset 進行過多次執行的情況,均是無效的。綜上所述,當且僅當沒有執行對通道數據的消費,Stop+drain 才是安全的。

在文檔中體現如下:

例如:假設程序尚未從 t.C 接收數據:

此外,上面的模式不是線程安全的,因為當消費完通道數據時,Stop 返回的值可能已經過時了,兩個 Goroutine 嘗試消費通道 C 數據也會導致死鎖。

(*time.Timer).Reset

這個方法更有意思,文檔很長,你可以在這里[4] 進行查看

文檔中一個有趣的摘錄:

請注意,因為在清空 channel 和計數器到期之間存在競爭條件,我們無法正確使用 Reset 返回值。Reset 方法必須作用于已停止或已過期的 channel 上。

文檔所提供 Reset 正確使用方法如下:

 

  1. if !t.Stop() {<-t.C}t.Reset(d) 

不能與來自通道的其他接收者同時使用 Stop 和 Reset 方法, 為了使 C 上傳遞的消息有效,C 應該在每次 重置 之前被消費完。

重置計時器而不清空它將使運行過程時丟棄該值,因為 C 緩存為 1,運行時對其他執行是有損發送[5]。

time.Timer: 把這些方法放在一起

  • Stop 僅作用在 New 和 Reset 方法之后才安全
  • Reset 僅在 Stop 方法后有效。
  • 只有在每次運行 Stop 后,channel 消費完時,所接收的值才是有效的。
  • 只有 channel 未被消費時,才允許清空 channel。

以下是計時器轉換,使用和調用關系流程圖:

 

你應該掌握的 Go 高級并發模式:計時器

 

timer.png

如下是一個正確復用計時器的例子,它解決了文章開頭提到的一些問題:

 

  1. func toChanTimed(t *time.Timer, ch chan int) {t.Reset(1 * time.Second)// No defer, as we don't know which// case will be selectedselect {case ch <- 42:case <-t.C:// C is drained, early returnreturn}// We still need to check the return value// of Stop, because t could have fired// between the send on ch and this line.if !t.Stop() {<-t.C}} 

上述代碼可以確保 toChanTimed 返回后可以重新使用計時器

責任編輯:華軒 來源: 今日頭條
相關推薦

2013-05-28 09:43:38

GoGo語言并發模式

2021-11-26 00:04:20

Go計時器重構

2011-05-31 16:50:35

Android 線程

2012-05-08 13:58:37

SharePoint

2024-01-29 00:35:00

Go并發開發

2021-03-26 09:10:11

Go 參透計時器

2021-12-07 11:30:32

Go煮蛋計時器

2011-09-08 14:01:01

Android Wid實例

2013-03-25 10:03:35

網絡優化網絡抑制快速認知網絡

2013-05-23 16:01:47

Android開發移動開發Chronometer

2023-12-29 08:10:41

Go并發開發

2010-01-05 15:00:30

.NET Framew

2023-09-26 01:21:34

2010-01-25 11:29:33

Android計時器

2022-06-23 07:23:34

自定義組件計時器

2023-04-17 09:08:27

CSS計時器

2024-04-11 07:40:55

Go并發編程

2022-11-07 08:02:45

Go命令工具

2024-05-06 07:53:09

Go并發編程

2021-08-09 14:47:34

Go語言開發
點贊
收藏

51CTO技術棧公眾號

日韩av新片网| 亚洲精品一级二级三级| 二区三区中文字幕| 精品视频一二| 国产精品一级二级三级| 日韩在线视频导航| 亚洲成人第一| 曰韩少妇与小伙激情| 欧美美女搞黄| www.成人在线视频| 久久精品主播| 欧美国产国产综合| 色偷偷av一区二区三区| 99免费视频观看| 精品中文字幕一区二区小辣椒 | 色噜噜狠狠色综合网图区 | 欧美特黄aaaaaaaa大片| 色诱亚洲精品久久久久久| 欧美日本二区| 亚洲综合久久久久| 不卡视频一区二区三区| 激情综合在线| 久久综合九色综合久99| 精品1区2区3区4区| 国产欧美韩日| 天堂蜜桃一区二区三区| 99热在线免费| 亚洲亚洲人成综合网络| 无码免费一区二区三区免费播放| 欧美日韩尤物久久| 成人午夜大片免费观看| 国产精品久久久久9999| 午夜国产视频| 欧美日韩综合| 欧美极品欧美精品欧美视频| 亚洲综合色在线| 亚洲国产综合人成综合网站| 亚洲国产婷婷香蕉久久久久久99| 99热这里只有精品首页| 国产一区免费在线| 久久国产精品免费| 成人欧美视频在线| 三级欧美日韩| 一本一道久久a久久精品逆3p| 99re6热在线精品视频播放| 91麻豆成人久久精品二区三区| 欧美日韩一区二区三区免费| 另类春色校园亚洲| 久久精品夜夜夜夜夜久久| 亚洲欧洲免费视频| 99热.com| 中文成人综合网| 久草.com| 欧美极品少妇xxxxx| 97一区二区国产好的精华液| 欧美大荫蒂xxx| 免费精品国产| 亚洲一区中文字幕在线观看| 欧美电影免费观看高清完整| 粉嫩久久99精品久久久久久夜| 国产99视频精品免费视频36| 日日摸夜夜添夜夜添亚洲女人| 日韩电影av| 午夜cr在线观看高清在线视频完整版| 日韩欧中文字幕| 里番在线观看网站| 色偷偷噜噜噜亚洲男人的天堂| 一区二区三区高清在线观看| 亚洲二区中文字幕| 欧美片网站免费| 国内偷自视频区视频综合| 国产日产高清欧美一区二区三区| 2019精品视频| 全球成人免费直播| 日本成人精品在线| 成人国产精品免费观看视频| 美女久久久久| 国产一区二区成人| 亚洲电影av| 欧美24videosex性欧美| 亚洲精品欧美精品| 中文国产成人精品| 国产精品热久久久久夜色精品三区| av综合网页| 免费a在线观看| 男人天堂网站在线| 另类少妇人与禽zozz0性伦| 91精品国产乱码久久久久久久| 亚洲视频在线观看一区二区三区| 91农村精品一区二区在线| 日本欧洲国产一区二区| 亚洲天堂中文字幕| 一区 二区 三区| 欧美高清电影在线看| 日韩精品一区中文字幕| 91在线高清观看| 乱妇乱女熟妇熟女网站| 99福利在线| 91超碰在线免费观看| 中文字幕亚洲综合久久菠萝蜜| 草莓视频一区二区三区| 免费一区二区三区在线观看| 国语自产精品视频在线看一大j8| 国产精品国产自产拍在线| 日韩激情图片| 特黄毛片在线观看| 国产九九热视频| 91丝袜脚交足在线播放| 亚洲国产女人aaa毛片在线| 国产麻豆午夜三级精品| 欧美xoxoxo| 日本aⅴ写真网站免费| 九九99久久| 久久精品国产96久久久香蕉| 18欧美亚洲精品| 中文一区二区| 精品一区毛片| 1区2区在线| 国产在线观看精品一区| 免费超爽大片黄| 亚洲xxxx做受欧美| 国产99亚洲| 99reav2| 国产高清不卡av| 久久精品在线视频| 欧美精品日韩一区| 亚洲黄色尤物视频| 成人精品小蝌蚪| 日本中文字幕一区二区视频| 国产精品久久久久久影院8一贰佰 国产精品久久久久久麻豆一区软件 | 最近2019中文字幕大全第二页 | 欧美大片网站在线观看 | 人人超碰在线| 欧美精品七区| 国产乱码精品一区二区三区日韩精品 | 日韩激情电影免费看| 日本不卡视频一区二区| 久久午夜夜伦鲁鲁一区二区| 国产午夜在线观看| 成人3d动漫在线观看| 国产精品影视| 在线观看欧美激情| 国产真实乱对白精彩久久| 日本孕妇大胆孕交无码| 男人在线视频资源| 九一免费在线观看| 国产av第一区| 蜜桃999成人看片在线观看| 国产精品久在线观看| 国产成人精品av在线| 国产一区av在线| 欧美性一级生活| 国产一区视频在线看| 欧美在线看片| 午夜精品av| 日韩国产欧美视频| 青青草国产成人99久久| 日韩av高清在线观看| 日本中文字幕不卡| 美女网站视频久久| 国内一区二区在线| 久久网站最新地址| 欧美国产一区在线| 亚洲国产综合在线| 99精品在线免费| 国产精品短视频| 中文字幕欧美一| 午夜欧美视频在线观看| 一本久久精品一区二区| 亚洲精品免费在线播放| 国产精品乱子久久久久| 国产suv精品一区二区6| 182在线播放| 成人在线日韩| 日韩精品诱惑一区?区三区| 97在线精品| 一区二区免费不卡在线| 亚洲尤物在线| 欧美国产日韩亚洲一区| 91极品美女在线| 久久九九国产精品怡红院 | 高清av不卡| 亚洲精品v亚洲精品v日韩精品| 欧美日韩精品在线一区| 精品一区二区国语对白| 亚洲精品亚洲人成人网在线播放| 欧美在线观看视频一区二区 | 日韩电影大全免费观看2023年上| 欧美大胆a视频| 中国丰满熟妇xxxx性| 超碰在线公开免费| 欧美性www| 国产精品人人爽人人做我的可爱| 亚洲色图另类色图| 欧美最新精品| 激情欧美一区二区| 国产日韩欧美精品在线| 亚洲国产精品悠悠久久琪琪| 亚洲aa中文字幕| a级黄色一级片|