昨天偶然閱讀pouch專案的原始碼發現有個kmutex
庫看了下**發現挺有意思的。根據chan的特性,進行上鎖、解鎖,某些場景下很是方便!
首先是結構體有兩個
type kmutex struct
type value struct
waits int32
}
kmutex
裡面有乙個互斥鎖跟乙個map型別,value
裡面有乙個chan 跟乙個int32型別
他們之間的關係,需要我用**解讀才能帶你領略,流程都是正常的從上到下
首先是new
func
new(
)*kmutex
ticker := time.
newticker
(time.minute)
gofunc()
} m.mutex.
unlock()
}}()
return m
}
首先是初始化struct
和map
,接下來他定義了乙個定時器然後一分鐘執行一次會把kmutex
中的map
key跟v全部清除.由於這不是乙個通用庫所以他們這個定時器我也不太確定是什麼意思,gc or 部分需求。
func
(m *kmutex)
lock
(k string
)bool
atomic.
addint32
(&v.waits,1)
defer atomic.
addint32
(&v.waits,-1
) m.mutex.
unlock()
<-v.c
return
true
}
重點的上鎖**首先互斥鎖上鎖,然後呼叫自身的乙個內部方法lock
,讓我看下這個函式的是啥原理吧
func
(m *kmutex)
lock
(k string)(
*value,
bool),
1), waits:0,
}return
nil,
true
}return v,
false
}
首先根據引數從map中獲取資料,如果map中沒有這個key,初始化這個key,並返回不存在,反之把獲取到的value返回,並且存在!
lock
函式的大致意思是根據key從map中判斷是否存在,不存在返回[nil,true]
,存在返回[values,false]
.
接著上面呼叫自身的lock
方法,如果返回true那麼直接宣布上鎖成功,因為如果lock
返回ture,代表這個key沒有被使用過。
接下來使用atomic
的原子性來記錄有多少人再等待獲取這個鎖。
首先+1,然後defer
-1看清楚是defer
代表著這行**要到函式return後才會執行
然後解鎖,然後再使用chan的特性堵塞住**!
func
(m *kmutex)
unlock
(k string)}
}
然後說下unlock
解鎖**,這裡就比較簡單,互斥鎖上鎖,根據key獲取vale然後判斷成功與否,跟chan裡面的數量,然後往chan裡面push值,這樣會解除chan帶來的堵塞!
剩下的lockwithtimeout
和trylock
我就說下trylock吧,lockwithtimeout**跟lock沒啥差別就是結尾做了個select判斷。
// trylock trys to lock, will not block.
func
(m *kmutex)
trylock
(k string
)bool
select
}
這段**再select都跟lock差不多,如果go基礎足夠深的話就能看出為啥。
如果select加上default的話那麼不會構成死鎖,並且不會堵塞!
上面的見解僅限於我個人,可能表達的不是很清楚,請諒解!比較語文作文沒及格過。原始碼需要多看多想!更重要的是多動手!
spring原始碼分析 spring原始碼分析
1.spring 執行原理 spring 啟動時讀取應用程式提供的 bean 配置資訊,並在 spring 容器中生成乙份相應的 bean 配置登錄檔,然後根據這張登錄檔例項化 bean,裝配好 bean 之間的依賴關係,為上 層應用提供準備就緒的執行環境。二 spring 原始碼分析 1.1spr...
思科VPP原始碼分析(dpo機制原始碼分析)
vpp的dpo機制跟路由緊密結合在一起。路由表查詢 ip4 lookup 的最後結果是乙個load balance t結構。該結構可以看做是乙個hash表,裡面包含了很多dpo,指向為下一步處理動作。每個dpo都是新增路由時的乙個path的結果。dpo標準型別有 dpo drop,dpo ip nu...
redux原始碼分析(三) 原始碼部分
下面是每個部分的一些解讀 createstore apicreatestore reducer,initialstate enhancer 曾經非常好奇這個函式的第二個引數到底是initialstate還是enhancer,因為見過兩種寫法都有的,以為是版本問題。看了原始碼才發現,都可以的。如果你不...