亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

通過使用 sync.Once 實現“完美單例”?

通過使用 sync.Once 實現“完美單例”?

Go
慕少森 2023-05-15 09:52:51
我很困惑,下面的片段是否完美?import "sync"import "sync/atomic"var initialized uint32var instance *singletonvar instance *singletonvar once sync.Oncefunc GetInstance() *singleton {    once.Do(func() {        instance = &singleton{}    })    return instance}atomic.StoreUint32(&initialized, 1)會將實例刷新到所有 CPU 嗎?我想我需要添加一個原子存儲和加載,例如下面的代碼片段var instance *singletonvar once sync.Oncefunc GetInstance() *singleton {    once.Do(func() {        atomic.StorePointer(&instance, &singleton{})    })    return atomic.LoadPointer(&instance)}我認為 Once.Do 只保證執行函數 f 一次。并且atomic.StoreUint32(&o.done, 1)只是 o.done 的內存屏障。它不能確保instance全局可見func (o *Once) Do(f func()) {    if atomic.LoadUint32(&o.done) == 1 {        return    }    // Slow-path.    o.m.Lock()    defer o.m.Unlock()    if o.done == 0 {        defer atomic.StoreUint32(&o.done, 1)        f()    }}
查看完整描述

1 回答

?
九州編程

TA貢獻1785條經驗 獲得超4個贊

讓我們將您的問題分解為兩部分:

  1. 單例

  2. 原子和 Go 內存模型

單例

Go 有包級變量。這些是在任何東西有機會移動之前實例化的,因此,如果您在使用包后立即創建這些東西,您將免費獲得一個單身人士。

package somepack


var(

  connection = createConn()

)


func Connection() SomeConnection {

  return connection

}

connection將被創建一次,因此Connection()將安全地返回它的相同實例。


有時,開發人員在需要“惰性”實例化時會使用單例。如果資源的創建成本很高且并非總是需要,那么這是一個好主意。這是sync.Once有用的地方。


var (

  connection SomeConnection // Not instantiated

  connectionOnce sync.Once

)


func Connection() SomeConnection {

  connectionOnce.Do(func(){

    connection = createConn()

  })


  return connection

}

請注意,我沒有對作業做任何特別的事情(例如,atomic.Store())。這是因為sync.Once處理了所有需要的鎖定以確保安全。


原子和 Go 內存模型

一個很好的開始資源是為此發布的文檔:The Go Memory Model


您對“刷新”到不同 CPU 的擔憂是有效的(盡管有一些評論),因為每個 CPU 都有自己的緩存和自己的狀態。C++(以及 Rust 等其他語言)開發人員傾向于關心這一點,因為他們會關心這一點。Go 開發人員不會太在意,因為 Go 只有“以前發生過”。Rust 實際上有一些不錯的文檔。


話雖這么說,你通常不需要擔心它?;コ怄i(和sync.Once)將強制每個 CPU 上的內存狀態達到您所期望的狀態。


查看完整回答
反對 回復 2023-05-15
  • 1 回答
  • 0 關注
  • 129 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號