<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在系統初始化的時候,某些程式碼只想被執行一次,這時應該怎麼做呢,沒有學習 Once 前,大家可能想到 宣告一個標識,表示是否初始化過,然後初始化這個標識加鎖,更新這個標識。
但是學會了 One 的使用可以更加簡單的解決這個問題
Once 包主要用於在並行執行程式碼的時候,某部分程式碼只會被執行 一次。
Once 的使用也非常簡單,Once 只有一個 Do 方法,接收一個無引數無返回值的函數型別的引數 f,不管呼叫多少次 Do 方法,引數 f 只在第一次呼叫 Do 方法時執行。
我們有一個Msg 引數,多個協程都會用到他,但是這個引數只用初始化一次就可以。
package main import ( "fmt" "sync" "time" ) var msg string func main() { var one sync.Once for i := 0; i < 5; i++ { go func(i int) { one.Do(func() { fmt.Printf("%d 執行初始化!n", i) msg = "Your Need Data" }) fmt.Println(msg) }(i) } time.Sleep(3* time.Second) }
執行結果如下:
可以看到初始化的程式碼只被4號執行緒執行了一次, 其他協程都是直接讀的初始化的資料,並沒有執行初始化的函數。
不要在 Do()
方法的引數方法中再次呼叫Do()
方法,因為執行這個Do()
方法的引數方法的時候,One 會持有一個鎖,如果再引數方法中再次呼叫Do()
方法,就會等待這個鎖釋放, 導致引數方法無法執行完畢,然後外層的Do 方法就一直無法釋放鎖,最後就成了死鎖。
錯誤範例:
package main import ( "fmt" "sync" ) var msg string var one sync.Once func main() { one.Do(fun1) } func fun1(){ fmt.Println("我是 fun1") one.Do(fun2) } func fun2(){ fmt.Println("我是 fun2") }
執行結果:
可以知道再 fun1()
中使用 Do()
方法呼叫 fun2
的時候形成了死鎖, 因為在 fun1()
執行過程中已將持有了該鎖,需要 fun1()
執行完畢才會釋放,然後因為使用 Do()
方法執行 fun2()
也會請求這個鎖, 會一直等待,導致 fun1()
不可能執行完, 也不可能釋放鎖。成了死鎖。
檢視原始碼
func (o *Once) Do(f func()) { if atomic.LoadUint32(&o.done) == 0 { // Outlined slow-path to allow inlining of the fast-path. o.doSlow(f) } } func (o *Once) doSlow(f func()) { o.m.Lock() defer o.m.Unlock() if o.done == 0 { defer atomic.StoreUint32(&o.done, 1) f() } }
使用一個原子類作為標識,加鎖校驗和操作原子類,保證只會被一個協程執行。
Do
呼叫了 doSlow
, 在 doSlow
中有defer
關鍵字,表示執行函數和釋放鎖是倒序執行,必須先執行完畢 if
判斷和裡面的 f()
才能釋放鎖。
到此這篇關於GoLang中的sync包Once使用執行範例的文章就介紹到這了,更多相關Go sync Once內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45