1 回答

TA貢獻1785條經驗 獲得超4個贊
讓我們將您的問題分解為兩部分:
單例
原子和 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 上的內存狀態達到您所期望的狀態。
- 1 回答
- 0 關注
- 129 瀏覽
添加回答
舉報