我在 Go 中有一個包含互斥鎖的結構,我想確保該互斥鎖從不nil。為此,我實現了一個GetMutex()函數,它檢查互斥鎖是否為 nil,如果是,則為其分配一個值。我的問題是:以下代碼線程安全嗎?如果不是,那么確保mux始終初始化的慣用方法是什么?我唯一能想到的就是在這個包中有一個全局互斥鎖,它在我的GetMutex()函數中使用,但也許有不同的方法。package mainimport ( "sync")type Counter struct { mux *sync.Mutex counter int}// Is this thread safe?func (c *Counter) GetMux() *sync.Mutex { if c.mux == nil { c.mux = &sync.Mutex{} } return c.mux}func (c *Counter) Inc() { c.GetMux().Lock() c.counter++ c.GetMux().Unlock()}func main() { c := &Counter{} c.Inc()}
1 回答

子衿沉夜
TA貢獻1828條經驗 獲得超3個贊
Counter.GetMux()不,如果同時從多個 goroutine 調用它是不安全的:GetMux()同時讀取和寫入Counter.mux字段。
一般的方法是使用類似“構造函數”的函數來處理初始化,如下所示:
func NewCounter() *Counter {
return &Counter{
mux: &sync.Mutex{},
}
}
當然,總是用 this 創建計數器NewCounter()。
另一種有限的方法是使用非指針互斥值:
type Counter struct {
mux sync.Mutex
counter int
}
因此,當您有一個Counter結構值時,它——按照設計——包括一個互斥體。但是,如果您這樣做,Counter則應始終將其用作指針,并且Counter不得復制結構值(否則互斥鎖字段也將被復制,但作為包文檔的sync狀態:“包含此包中定義的類型的值不應被復制。”)。
這樣做的明顯優勢是零值是Counter一個有效且準備好的計數器(您應該針對您的自定義類型),并且不需要構造函數。
- 1 回答
- 0 關注
- 119 瀏覽
添加回答
舉報
0/150
提交
取消