




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第Go并發(fā)同步Mutex典型易錯(cuò)使用場(chǎng)景目錄Mutex的4種易錯(cuò)使用場(chǎng)景1.Lock/Unlock不成對(duì)出現(xiàn)2.Copy已使用的Mutex3.重入4.死鎖解決策略
Mutex的4種易錯(cuò)使用場(chǎng)景
1.Lock/Unlock不成對(duì)出現(xiàn)
Lock/Unlock沒有成對(duì)出現(xiàn),就可能會(huì)出現(xiàn)死鎖或者是因?yàn)閁nlock一個(gè)未加鎖的Mutex而導(dǎo)致panic。
忘記Unlock的情形
代碼中有太多的if-else分支,可能在某個(gè)分支中漏寫了Unlock;在重構(gòu)的時(shí)候把Unlock給刪除了;Unlock誤寫成了Lock。
忘記Lock的情形一般是誤刪除了或者注釋掉了Lock。
eg:
funcmain(){
varmusync.Mutex
defermu.Unlock()
fmt.Println("oh,missingLock!")
errorresult:
2.Copy已使用的Mutex
實(shí)際上sync包下的同步原語在使用后都是不可復(fù)制的,原因在于Mutex是有狀態(tài)的,其state的值時(shí)刻在變化,如果復(fù)制一個(gè)已經(jīng)加鎖的Metux對(duì)象給一個(gè)新的變量,可能這個(gè)變量剛初始化就顯示被加鎖了,這顯然是不合理的。
eg:以下代碼在調(diào)用foo函數(shù)的時(shí)候,調(diào)用者會(huì)復(fù)制Mutex變量c作為foo函數(shù)的參數(shù),不幸的是,復(fù)制之前已經(jīng)使用了這個(gè)鎖,這就導(dǎo)致,復(fù)制的Counter是一個(gè)帶狀態(tài)Counter,從而會(huì)導(dǎo)致死鎖。
typeCounterstruct{
sync.Mutex
Countint
funcmain(){
varcCounter
c.Lock()
deferc.Unlock()
c.Count++
foo(c)//復(fù)制鎖
//這里Counter的參數(shù)是通過復(fù)制的方式傳入的
funcfoo(cCounter){
c.Lock()
deferc.Unlock()
fmt.Println("infoo")
errorresult:還好有Go的協(xié)程死鎖檢查機(jī)制,程序運(yùn)行后會(huì)快速失敗而不是一直hang住。
GoVet指令
我們當(dāng)然不想程序運(yùn)行了才發(fā)現(xiàn)死鎖,我們可以通過govet指令來在運(yùn)行前檢查我們的代碼是否存在lockcopy問題:
檢查原理
檢查是通過copylock分析器靜態(tài)分析實(shí)現(xiàn)的。這個(gè)分析器會(huì)分析函數(shù)調(diào)用、range遍歷、復(fù)制、聲明、函數(shù)返回值等位置,有沒有鎖的值copy的情景,以此來判斷有沒有問題。
通過源碼我們可以看到實(shí)現(xiàn)了Lock或者Unlock接口的struct都支持copylock檢查。
varlockerType*types.Interface
//Constructasync.Lockerinterfacetype.
funcinit(){
nullary:=types.NewSignature(nil,nil,nil,false)//func()
methods:=[]*types.Func{
types.NewFunc(token.NoPos,nil,"Lock",nullary),
types.NewFunc(token.NoPos,nil,"Unlock",nullary),
lockerType=types.NewInterface(methods,nil).Complete()
3.重入
Mutex不像Java中的ReentrantLock擁有可重入的功能,主要是因?yàn)槠鋵?shí)現(xiàn)中沒有標(biāo)記位記錄哪個(gè)goroutine擁有這把鎖,所以Mutex是一個(gè)不可重入鎖,而一旦誤用Mutex的重入就會(huì)報(bào)錯(cuò)。
eg:
funcfoo(lsync.Locker){
fmt.Println("infoo")
l.Lock()
bar(l)
l.Unlock()
funcbar(lsync.Locker){
l.Lock()
fmt.Println("inbar")
l.Unlock()
funcmain(){
l:=amp;sync.Mutex{}
foo(l)
errorresult:我們可以看到當(dāng)在bar方法中嘗試再次獲取鎖時(shí),獲取不到,觸發(fā)了死鎖。
4.死鎖
兩個(gè)或兩個(gè)以上的進(jìn)程(或線程,goroutine)
執(zhí)行過程中,因爭奪共享資源而處于一種互相等待的狀態(tài),如果沒有外部干涉,它們都將無法推進(jìn)下去,此時(shí),我們稱系統(tǒng)處于死鎖狀態(tài)或系統(tǒng)產(chǎn)生了死鎖。
死鎖產(chǎn)生的4個(gè)必要條件
如果想避免死鎖,我們只要思考如何打破以下任意條件就可以。
1.互斥:至少一個(gè)資源是被排他性獨(dú)享的,其他線程必須處于等待狀態(tài),直到資源被釋放。2.持有和等待:goroutine持有一個(gè)資源,并且還在請(qǐng)求其它goroutine持有的資源,也就是咱們常說的吃著碗里,看著鍋里的意思。3.不可剝奪:資源只能由持有它的goroutine來釋放。4.環(huán)路等待:一般來說,存在一組等待進(jìn)程,P={P1,P2,,PN},P1等待P2持有的
資源,P2等待P3持有的資源,依此類推,最后是PN等待P1持有的資源,這就形成
了一個(gè)環(huán)路等待的死結(jié)。
eg:在這里我們以辦理居住證業(yè)務(wù),舉一個(gè)簡單的環(huán)路等待導(dǎo)致死鎖的例子:
//辦理居住證
funcmain(){
//網(wǎng)簽中心證明
varpsCertificatesync.Mutex
//社區(qū)證明
varpropertyCertificatesync.Mutex
varwgsync.WaitGroup
wg.Add(2)//需要網(wǎng)簽中心和社區(qū)都處理
//網(wǎng)簽中心處理goroutine
gofunc(){
deferwg.Done()//網(wǎng)簽中心處理完成
psCertificate.Lock()
deferpsCertificate.Unlock()
//檢查材料
time.Sleep(5*time.Second)
//請(qǐng)求社區(qū)的證明
propertyCertificate.Lock()
propertyCertificate.Unlock()
//社區(qū)處理goroutine
gofunc(){
deferwg.Done()//社區(qū)處理完成
propertyCertificate.Lock()
deferpropertyCertificate.Unlock()
//檢查材料
time.Sleep(5*time.Second)
//請(qǐng)求網(wǎng)簽中心的證明
psCertificate.Lock()
psCertificate.Unlock()
wg.Wait()
fmt.Println("成功完成")
errorresult:
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 北師大版二年級(jí)下冊(cè)第5單元語文試卷A卷
- 北京版四年級(jí)上冊(cè)期中測(cè)試語文試卷
- 2025年茅臺(tái)酒項(xiàng)目招商引資報(bào)告
- 基礎(chǔ)知識(shí)精練課件:3.3 第2課時(shí) 多項(xiàng)式
- 一年級(jí)上冊(cè)綜合實(shí)踐活動(dòng)計(jì)劃
- 胸腔腫物護(hù)理個(gè)案教育
- 老年人群體公共衛(wèi)生服務(wù)管理流程
- 永不放棄心理健康教育主題班會(huì)
- 劉志軍案件對(duì)金融行業(yè)合規(guī)管理的心得體會(huì)
- 桂林智能制造項(xiàng)目可行性分析報(bào)告
- 海水的淡化技術(shù)及應(yīng)用
- 叮咚智能鎖說明書
- 嘉世咨詢 -2024眼科診療行業(yè)簡析報(bào)告
- 手機(jī)拍攝短視頻
- DB32T 4719-2024酒店服務(wù)與廚師職業(yè)技能等級(jí)認(rèn)定工作規(guī)范
- 2024年湖南省郴州湘能農(nóng)電服務(wù)有限公司招聘筆試參考題庫含答案解析
- 加油站安全風(fēng)險(xiǎn)分級(jí)管控和隱患排查治理雙重預(yù)防機(jī)制運(yùn)行手冊(cè)
- 2024年度安徽白帝集團(tuán)限公司社會(huì)招聘高頻考題難、易錯(cuò)點(diǎn)模擬試題(共500題)附帶答案詳解
- 2023年遼寧卷物理高考試卷(含答案)
- 攻博計(jì)劃書模版
- 2013黑龍江公務(wù)員職位表
評(píng)論
0/150
提交評(píng)論