国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Golang - golang 自旋鎖的實現

golang 自旋鎖的實現

2020-05-21 10:40one_zheng Golang

這篇文章主要介紹了golang 自旋鎖的實現,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

CAS算法(compare and swap)

CAS算法是一種有名的無鎖算法。無鎖編程,即不使用鎖的情況下實現多線程之間的變量同步,也就是在沒有線程被阻塞的情況下實現變量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。CAS算法涉及到三個操作數

  • 需要讀寫的內存值V
  • 進行比較的值A
  • 擬寫入的新值B

當且僅當 V 的值等于 A時,CAS通過原子方式用新值B來更新V的值,否則不會執行任何操作(比較和替換是一個原子操作)。一般情況下是一個自旋操作,即不斷的重試。

自旋鎖

自旋鎖是指當一個線程在獲取鎖的時候,如果鎖已經被其他線程獲取,那么該線程將循環等待,然后不斷地判斷是否能夠被成功獲取,知直到獲取到鎖才會退出循環。

獲取鎖的線程一直處于活躍狀態,但是并沒有執行任何有效的任務,使用這種鎖會造成 busy-waiting 。

它是為實現保護共享資源而提出的一種鎖機制。其實,自旋鎖與互斥鎖比較類似,它們都是為了解決某項資源的互斥使用。無論是互斥鎖,還是自旋鎖,在任何時刻,最多只能由一個保持者,也就說,在任何時刻最多只能有一個執行單元獲得鎖。但是兩者在調度機制上略有不同。對于互斥鎖,如果資源已經被占用,資源申請者只能進入睡眠狀態。但是自旋鎖不會引起調用者睡眠,如果自旋鎖已經被別的執行單元保持,調用者就一直循環在那里看是否該自旋鎖的保持者已經釋放了鎖,“自旋”一詞就是因此而得名。

golang實現自旋鎖

?
1
2
3
4
5
6
7
8
9
10
11
12
13
type spinLock uint32
func (sl *spinLock) Lock() {
  for !atomic.CompareAndSwapUint32((*uint32)(sl), 0, 1) {
    runtime.Gosched()
  }
}
func (sl *spinLock) Unlock() {
  atomic.StoreUint32((*uint32)(sl), 0)
}
func NewSpinLock() sync.Locker {
  var lock spinLock
  return &lock
}

可重入的自旋鎖和不可重入的自旋鎖

文章開始的時候的那段代碼,仔細分析一下就可以看出,它是不支持重入的,即當一個線程第一次已經獲取到了該鎖,在鎖釋放之前又一次重新獲取該鎖,第二次就不能成功獲取到。由于不滿足CAS,所以第二次獲取會進入while循環等待,而如果是可重入鎖,第二次也是應該能夠成功獲取到的。

而且,即使第二次能夠成功獲取,那么當第一次釋放鎖的時候,第二次獲取到的鎖也會被釋放,而這是不合理的。

為了實現可重入鎖,我們需要引入一個計數器,用來記錄獲取鎖的線程數

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
type spinLock struct {
   owner int
   count int
}
 
func (sl *spinLock) Lock() {
    me := GetGoroutineId()
    if spinLock .owner == me { // 如果當前線程已經獲取到了鎖,線程數增加一,然后返回
        sl.count++
        return
    }
    // 如果沒獲取到鎖,則通過CAS自旋
  for !atomic.CompareAndSwapUint32((*uint32)(sl), 0, 1) {
    runtime.Gosched()
  }
}
func (sl *spinLock) Unlock() {
   if rl.owner != GetGoroutineId() {
     panic("illegalMonitorStateError")
   }
   if sl.count >0 { // 如果大于0,表示當前線程多次獲取了該鎖,釋放鎖通過count減一來模擬
      sl.count--
    }else { // 如果count==0,可以將鎖釋放,這樣就能保證獲取鎖的次數與釋放鎖的次數是一致的了。
      atomic.StoreUint32((*uint32)(sl), 0)
    }
}
 
func GetGoroutineId() int {
  defer func() {
    if err := recover(); err != nil {
      fmt.Println("panic recover:panic info:%v", err)   }
  }()
 
  var buf [64]byte
  n := runtime.Stack(buf[:], false)
  idField := strings.Fields(strings.TrimPrefix(string(buf[:n]), "goroutine "))[0]
  id, err := strconv.Atoi(idField)
  if err != nil {
    panic(fmt.Sprintf("cannot get goroutine id: %v", err))
  }
  return id
}
 
 
func NewSpinLock() sync.Locker {
  var lock spinLock
  return &lock
}

自旋鎖的其他變種

1. TicketLock

TicketLock主要解決的是公平性的問題。

思路:每當有線程獲取鎖的時候,就給該線程分配一個遞增的id,我們稱之為排隊號,同時,鎖對應一個服務號,每當有線程釋放鎖,服務號就會遞增,此時如果服務號與某個線程排隊號一致,那么該線程就獲得鎖,由于排隊號是遞增的,所以就保證了最先請求獲取鎖的線程可以最先獲取到鎖,就實現了公平性。

可以想象成銀行辦理業務排隊,排隊的每一個顧客都代表一個需要請求鎖的線程,而銀行服務窗口表示鎖,每當有窗口服務完成就把自己的服務號加一,此時在排隊的所有顧客中,只有自己的排隊號與服務號一致的才可以得到服務。

2. CLHLock

CLH鎖是一種基于鏈表的可擴展、高性能、公平的自旋鎖,申請線程只在本地變量上自旋,它不斷輪詢前驅的狀態,如果發現前驅釋放了鎖就結束自旋,獲得鎖。

3. MCSLock

MCSLock則是對本地變量的節點進行循環。

4. CLHLock 和 MCSLock

都是基于鏈表,不同的是CLHLock是基于隱式鏈表,沒有真正的后續節點屬性,MCSLock是顯示鏈表,有一個指向后續節點的屬性。

將獲取鎖的線程狀態借助節點(node)保存,每個線程都有一份獨立的節點,這樣就解決了TicketLock多處理器緩存同步的問題。

自旋鎖與互斥鎖

  • 自旋鎖與互斥鎖都是為了實現保護資源共享的機制。
  • 無論是自旋鎖還是互斥鎖,在任意時刻,都最多只能有一個保持者。
  • 獲取互斥鎖的線程,如果鎖已經被占用,則該線程將進入睡眠狀態;獲取自旋鎖的線程則不會睡眠,而是一直循環等待鎖釋放。

總結:

  • 自旋鎖:線程獲取鎖的時候,如果鎖被其他線程持有,則當前線程將循環等待,直到獲取到鎖。
  • 自旋鎖等待期間,線程的狀態不會改變,線程一直是用戶態并且是活動的(active)。
  • 自旋鎖如果持有鎖的時間太長,則會導致其它等待獲取鎖的線程耗盡CPU。
  • 自旋鎖本身無法保證公平性,同時也無法保證可重入性。
  • 基于自旋鎖,可以實現具備公平性和可重入性質的鎖。
  • TicketLock:采用類似銀行排號叫好的方式實現自旋鎖的公平性,但是由于不停的讀取serviceNum,每次讀寫操作都必須在多個處理器緩存之間進行緩存同步,這會導致繁重的系統總線和內存的流量,大大降低系統整體的性能。
  • CLHLock和MCSLock通過鏈表的方式避免了減少了處理器緩存同步,極大的提高了性能,區別在于CLHLock是通過輪詢其前驅節點的狀態,而MCS則是查看當前節點的鎖狀態。
  • CLHLock在NUMA架構下使用會存在問題。在沒有cache的NUMA系統架構中,由于CLHLock是在當前節點的前一個節點上自旋,NUMA架構中處理器訪問本地內存的速度高于通過網絡訪問其他節點的內存,所以CLHLock在NUMA架構上不是最優的自旋鎖。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://studygolang.com/articles/16480

延伸 · 閱讀

精彩推薦
  • Golanggolang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    a165861639710342021-03-08
  • Golanggolang json.Marshal 特殊html字符被轉義的解決方法

    golang json.Marshal 特殊html字符被轉義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉義的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧 ...

    李浩的life12792020-05-27
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

    本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
  • GolangGolang通脈之數據類型詳情

    Golang通脈之數據類型詳情

    這篇文章主要介紹了Golang通脈之數據類型,在編程語言中標識符就是定義的具有某種意義的詞,比如變量名、常量名、函數名等等,Go語言中標識符允許由...

    4272021-11-24
  • Golanggolang的httpserver優雅重啟方法詳解

    golang的httpserver優雅重啟方法詳解

    這篇文章主要給大家介紹了關于golang的httpserver優雅重啟的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    helight2992020-05-14
  • Golanggo日志系統logrus顯示文件和行號的操作

    go日志系統logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統logrus顯示文件和行號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
  • Golanggolang如何使用struct的tag屬性的詳細介紹

    golang如何使用struct的tag屬性的詳細介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細介紹,從例子說起,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看...

    Go語言中文網11352020-05-21
  • GolangGolang中Bit數組的實現方式

    Golang中Bit數組的實現方式

    這篇文章主要介紹了Golang中Bit數組的實現方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    天易獨尊11682021-06-09
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 久久久亚洲精品视频 | 看真人视频a级毛片 | 亚洲精品一| 国产乱xxxxx97国语对白 | 国产在线精品一区 | 国产成人综合一区二区三区 | a久久| 91精品久久久久久久久久入口 | 久久一二区 | 欧美日韩第一页 | 日韩av电影在线免费观看 | 国产成人网 | 成人精品视频 | 天天操天天射天天 | 亚洲欧美国产另类 | 日韩三级观看 | 影音先锋亚洲资源 | 精品久久久久久国产 | 国产一区欧美 | 欧美日韩一区二区三区不卡视频 | 成人免费一区二区三区视频软件 | 国产欧美日韩二区 | 日韩一区二区三区在线观看 | 婷婷精品久久久久久久久久不卡 | 日韩一级 | 免费成人在线看 | 欧州一区二区三区 | 亚洲精品专区 | 亚洲 视频 一区 | 国产精品69毛片高清亚洲 | 国产视频精品免费 | 亚洲一区二区三区在线 | 91成人免费看 | 狠狠干狠狠操 | 免费观看黄视频网站 | 一区二区三区免费看 | 国产激情午夜 | 最近日韩中文字幕 | 成人黄网在线观看 | 亚洲一区视频在线 | 中文字幕 视频一区 |