2017-06-17 76 views
-1

由於golang的初學者,我覺得互斥golang的不是從書The Go Programming Language重新entranceLock。他們解釋原因如下:時我們將使用不會重新進入鎖定

Go的互斥鎖沒有重入是有好處的。互斥體的目的是確保在程序執行期間,共享變量的某些不變式保持在臨界點。其中一個不變量是「沒有goroutine正在訪問共享變量」,但可能會有額外的不變量特定於互斥量守衛的數據結構。當一個goroutine獲得一個互斥鎖時,它可以假定不變量持有。雖然它擁有 鎖,但它可以更新共享變量,以便暫時違反不變量。 但是,當它釋放鎖定時,它必須保證順序已經恢復,並且不變量再次保持。雖然可重入互斥體將確保沒有其他goroutines正在訪問共享變量,但它無法保護這些變量的其他不變量。

它似乎解釋是足夠的細節,不幸我無法得到它。我仍然不知道什麼時候我們應該用不能重新進入鎖,如果不是我會收到什麼不好的驚喜?如果有人能給我一個例子,我會很感激。

回答

0

這裏是代碼的例子只是爲了說明問題:

package main 

import (
    "fmt" 
    "sync" 
) 

type SafeCounter struct { 
    lock  sync.Mutex 
    count  int 
    enabled bool 
    NextValue func(int) int 
} 

const maxCount = 10 

func (c *SafeCounter) Count() int { 
    return c.count 
} 

func (c *SafeCounter) Increment() { 
    c.lock.Lock() 
    if c.enabled { 
     c.count = c.NextValue(c.count) 
    } 
    c.lock.Unlock() 
} 

func (c *SafeCounter) SetEnabled(enabled bool) { 
    c.lock.Lock() 
    c.enabled = enabled 
    if !enabled { 
     c.count = 0 
    } 
    c.lock.Unlock() 
} 

func main() { 
    var counter SafeCounter 
    counter.SetEnabled(true) 
    counter.NextValue = func(value int) int { 
     if counter.Count() > maxCount { 
      // Safe counter doesn't expect this here! 
      // The program will panic in SetEnabled 
      counter.SetEnabled(false) 
     } 
     return value + 1 
    } 
    for i := 0; i < 100; i++ { 
     doAction() 
     counter.Increment() 
    } 
    fmt.Println(counter.Count()) 
} 

func doAction() { 
    // some action 
} 

兩個IncrementSetEnabled獲取鎖,因爲他們不能容忍的enabledcount值改變,而他們在中間的東西。但是,如果鎖是可重入的(遞歸),那麼它將被允許(因爲兩個調用都在同一個goroutine上運行)。

相關問題