iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 29
0

用法說明

在經過幾個package都看到位移處理的寫法,終於找個時間用心研究一下,一切都是為了能夠更一進步了解某些package的內容。

以sync裡面的mutex為例,有段程式碼如下

const (
    mutexLocked      = 1 << iota 
    mutexWoken                  
    mutexStarving                
    mutexWaiterShift = iota 
)

一開始看得時候根本一頭霧水。

『<<』和『>>』是位移處理的動作,看到這兩個符號分別是表示『左位移』和『右位移』。

而且這個位移都是2進位的處理,沒有其他進制了。

如int32型態,其實表示轉成2進位,有32個位元,也等於有32個bit的意思。

十進位的1 = 2進制的 00000000000000000000000000000001
十進位的2 = 2進制的 00000000000000000000000000000010
十進位的3 = 2進制的 00000000000000000000000000000011
十進位的4 = 2進制的 00000000000000000000000000000100

上面的範例code還加上iota這個小東西,這是golang的關鍵字,意思是根據規則,往下照順序排,最初始值為1,而且不重複。

先不看位元運算的話

const (
	a1 =  iota
	a2
	a3
	a4
	a5
)

a1 到a5分別會是 0、1、2、3、4。

那如果搭配位元運算呢?

1 << iota 表示每次往左移一位

所以實際上數值會是這樣子

const (
    mutexLocked      = 1 << iota  // 1   (00001)
    mutexWoken                    // 2   (00010)
    mutexStarving                 // 4   (00100)
    mutexWaiterShift = iota       // 3   因為回歸正常,1和2已經用過,所以從3開始
)

目的

有時候一個業務處理,甚至說是一個比較複雜處理的運算核心,往往會需要許多狀態來紀錄。

若每個狀態都開一個變數來紀錄,其實非常麻煩。

若狀態的表示只是像開關,不是開就是關,不是1就是0,那其實就像伯努利分布一樣。

2進位的表示方式,每個bit不是1就是0,所以這個方法,是把每個bit是不互相影響的個體,每個bit主管一個狀態的開關。

1代表開,0代表關,同時可以存在很多bit是開的狀態,或者多個同是關的狀態。

最後,再加上一個很重要的關鍵,如果把這個核心的所有狀態放在一個變數就可以處理或變更。

那我使用lock的效能就非常優異,實際上sync這個package使用了atomic的方式,來對這個變數,也就是這整個核心的狀態做變更,達到原子性的目的。


上一篇
Day28 .[心得與討論篇] embedded 嵌入
下一篇
Day30 .[心得與討論篇] 還有好多講不完的心得
系列文
Let's Eat GO ! 實務開發雜談by Golang30

尚未有邦友留言

立即登入留言