?
This document uses PHP Chinese website manual Release
import "sync"
概觀
索引
示例
子目錄
程序包 sync 提供基本的同步原語,如互斥鎖。除了 Once 和 WaitGroup 類型之外,大多數(shù)類型都是供低級庫例程使用的。通過 Channel 和溝通可以更好地完成更高級別的同步。
包含此程序包中定義的類型的值不應被復制。
type Cond
func NewCond(l Locker) *Cond
func (c *Cond) Broadcast()
func (c *Cond) Signal()
func (c *Cond) Wait()
type Locker
type Map
func (m *Map) Delete(key interface{})
func (m *Map) Load(key interface{}) (value interface{}, ok bool)
func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool)
func (m *Map) Range(f func(key, value interface{}) bool)
func (m *Map) Store(key, value interface{})
type Mutex
func (m *Mutex) Lock()
func (m *Mutex) Unlock()
type Once
func (o *Once) Do(f func())
type Pool
func (p *Pool) Get() interface{}
func (p *Pool) Put(x interface{})
type RWMutex
func (rw *RWMutex) Lock()
func (rw *RWMutex) RLock()
func (rw *RWMutex) RLocker() Locker
func (rw *RWMutex) RUnlock()
func (rw *RWMutex) Unlock()
type WaitGroup
func (wg *WaitGroup) Add(delta int)
func (wg *WaitGroup) Done()
func (wg *WaitGroup) Wait()
一旦 Pool WaitGroup
cond.go map.go mutex.go once.go pool.go runtime.go rwmutex.go waitgroup.go
Cond 實現(xiàn)了一個條件變量,用于等待或通告事件發(fā)生的 goroutine 的集合點。
每個 Cond 都有一個關聯(lián)的 Locker L (通常是 * Mutex 或 * RWMutex ),在更改條件和調(diào)用 Wait 方法時必須保持該 L。
首次使用后不得復制 Cond 。
type Cond struct { // L is held while observing or changing the condition L Locker // contains filtered or unexported fields}
func NewCond(l Locker) *Cond
NewCond 返回一個帶有 Locker L 的新 Cond 。
func (c *Cond) Broadcast()
廣播喚醒等待的所有 goroutines c 。
在通話過程中,主叫方可以允許但不是必需的。
func (c *Cond) Signal()
如果有任何信號,信號喚醒一個等待在 c 上的 goroutine 。
在調(diào)用過程中,調(diào)用方可以允許但不是必需的。
func (c *Cond) Wait()
等待原子的解鎖 c.L 并暫停執(zhí)行調(diào)用的 goroutine 。在稍后恢復執(zhí)行后, Wait 在返回之前鎖定 c.L 。與其他系統(tǒng)不同,除非廣播或信號喚醒,否則 Wait 不能返回。
因為當 Wait 第一次恢復時 c.L 沒有被鎖定,所以當 Wait 返回時,調(diào)用者通常不能認為條件為真。相反,調(diào)用者應該等待一個循環(huán):
c.L.Lock()for !condition() { c.Wait()}... make use of condition ...c.L.Unlock()
Locker 表示可以鎖定和解鎖的物體。
type Locker interface { Lock() Unlock()}
Map 是一個并發(fā)映射,包含分期恒定時間加載,存儲和刪除。多個 goroutines 同時調(diào)用 Map 的方法是安全的。
它針對并發(fā)循環(huán)進行了優(yōu)化,使用的密鑰隨時間保持穩(wěn)定,并且只有少數(shù)穩(wěn)態(tài)存儲,或者每個密鑰存儲在一個 goroutine 中。
對于不共享這些屬性的用例,與使用讀寫互斥鎖配對的普通映射相比,它可能具有可比較或更差的性能以及更差的類型安全性。
零映射有效且為空。
首次使用后不得復制 Map 。
type Map struct { // contains filtered or unexported fields}
func (m *Map) Delete(key interface{})
Delete 刪除鍵的值。
func (m *Map) Load(key interface{}) (value interface{}, ok bool)
加載返回鍵映射中存儲的值,如果沒有值,則返回零。ok 的結果表示在地圖中是否找到了值。
func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool)
LoadOrStore 返回鍵的現(xiàn)有值(如果存在)。否則,它存儲并返回給定的值。如果加載的值加載結果為 true ,如果存儲則加載為 false 。
func (m *Map) Range(f func(key, value interface{}) bool)
范圍按順序為地圖中存在的每個鍵和值調(diào)用 f 。如果 f 返回 false ,范圍將停止迭代。
范圍不一定對應于 Map 內(nèi)容的任何一致快照:不會有多次訪問密鑰,但如果同時存儲或刪除任何密鑰的值,則范圍可能反映該范圍內(nèi)任何點的該密鑰的任何映射調(diào)用。
范圍可能是 O(N) 與映射中的元素數(shù)量,即使f在常數(shù)調(diào)用后返回 false 也是如此。
func (m *Map) Store(key, value interface{})
存儲設置密鑰的值。
Mutex 是互斥鎖。Mutex 的零值是一個解鎖的互斥鎖。
第一次使用后不得復制 Mutex 。
type Mutex struct { // contains filtered or unexported fields}
func (m *Mutex) Lock()
Lock 鎖住 m 。如果鎖已在使用中,則調(diào)用 goroutine 將阻塞,直到互斥鎖可用。
func (m *Mutex) Unlock()
Unlock 解鎖 m 。如果 m 未鎖定進入解鎖,則為運行時錯誤。
鎖定的互斥鎖與特定的 goroutine 沒有關聯(lián)。允許一個 goroutine 鎖定一個 Mutex ,然后安排另一個 goroutine 來解鎖它。
一旦一個對象會執(zhí)行一個動作。
type Once struct { // contains filtered or unexported fields}
package mainimport ("fmt""sync")func main() {var once sync.Once onceBody := func() { fmt.Println("Only once")} done := make(chan bool)for i := 0; i < 10; i++ { go func() { once.Do(onceBody) done <- true}()}for i := 0; i < 10; i++ {<-done}}
func (o *Once) Do(f func())
當且僅當?shù)谝淮螢檫@個 Once 實例調(diào)用 Do時,才調(diào)用函數(shù) f 。換句話說,給出
var once Once
如果一次 .Do(f) 被多次調(diào)用,只有第一次調(diào)用會調(diào)用f,即使 f 在每次調(diào)用中都有不同的值。一個新的實例需要執(zhí)行每個函數(shù)。
Do 是用于初始化的,只能運行一次。由于 f 是 niladic,因此可能需要使用函數(shù)文字來捕獲由 Do 調(diào)用的函數(shù)的參數(shù):
config.once.Do(func() { config.init(filename) })
由于沒有對 Do 的調(diào)用返回,直到對 f 的一次調(diào)用返回,如果 f 導致 Do 被調(diào)用,它將會死鎖。
如果 f 終止, Do 認為它已經(jīng)返回; 未來的調(diào)用返回而不調(diào)用 f 。
Pool 是一組可以單獨保存和檢索的臨時對象。
存儲在 Pool 中的任何項目可能會隨時自動刪除,而無需通知。如果 Pool 在這種情況發(fā)生時只有唯一的引用,則該項可能會被釋放。
Pool 可以同時用于多個 goroutine 。
Pool 的目的是緩存已分配但未使用的項目以備后用,以減輕垃圾收集器的壓力。也就是說,它可以輕松構建高效,線程安全的免費列表。但是,它不適用于所有不受限制的列表。
Pool 的適當使用是管理一組臨時項目,這些臨時項目在一個程序包的并發(fā)獨立客戶端之間悄悄共享并可能被重用。Pool 提供了一種方法來緩解跨多個客戶端的分配開銷。
fmt 包中有一個很好地使用 Pool 的例子,它維護一個動態(tài)大小的臨時輸出緩沖區(qū)存儲區(qū)。商店在負載下(當許多 goroutines 正在活動時)縮小,靜止時縮小。
另一方面,作為短期對象的一部分而維護的空閑列表對于 Pool 來說并不適合,因為在該場景中開銷不能很好地分攤。讓這些對象實現(xiàn)自己的不受限制的列表會更高效。
首次使用后不得復制 Pool 。
type Pool struct { // New optionally specifies a function to generate // a value when Get would otherwise return nil. // It may not be changed concurrently with calls to Get. New func() interface{} // contains filtered or unexported fields}
package mainimport ("bytes""io""os""sync""time")var bufPool = sync.Pool{ New: func() interface{} {// The Pool's New function should generally only return pointer// types, since a pointer can be put into the return interface// value without an allocation:return new(bytes.Buffer)},}// timeNow is a fake version of time.Now for tests.func timeNow() time.Time {return time.Unix(1136214245, 0)}func Log(w io.Writer, key, val string) { b := bufPool.Get().(*bytes.Buffer) b.Reset()// Replace this with time.Now() in a real logger. b.WriteString(timeNow().UTC().Format(time.RFC3339)) b.WriteByte(' ') b.WriteString(key) b.WriteByte('=') b.WriteString(val) w.Write(b.Bytes()) bufPool.Put(b)}func main() {Log(os.Stdout, "path", "/search?q=flowers")}
func (p *Pool) Get() interface{}
從 Pool 中選擇一個任意項目,將其從池中刪除,并將其返回給調(diào)用者。獲取可能會選擇忽略 Pool 并將其視為空。調(diào)用者不應承擔傳遞給 Put 的值與 Get 返回的值之間的任何關系。
如果 Get 以其他方式返回 nil ,并且 p.New 不為零,則 Get 返回調(diào)用 p.New 的結果。
func (p *Pool) Put(x interface{})
Put 將 x 添加到 Pool 中。
RWMutex 是讀寫器互斥鎖。該鎖可以由任意數(shù)量的讀者或單個作者持有。 RWMutex 的零值是一個解鎖的互斥鎖。
首次使用后,RWMutex 不得被復制。
如果一個 goroutine 持有一個 RWMutex 用于讀取,另一個 goroutine 可能調(diào)用 Lock ,那么在最初的讀取鎖定被釋放之前,沒有 goroutine 應該期望能夠獲得讀取鎖定。特別是,這禁止了遞歸讀取鎖定。這是為了確保鎖最終可用; 被鎖定的鎖定呼叫不包括新讀取器獲取鎖定。
type RWMutex struct { // contains filtered or unexported fields}
func (rw *RWMutex) Lock()
Lock 鎖定 rw 寫入。如果鎖已被鎖定以進行讀取或寫入,則 Lock 塊直到鎖可用。
func (rw *RWMutex) RLock()
RLock 鎖定 rw 閱讀。
它不應該用于遞歸讀鎖定;被鎖定的鎖定呼叫不包括新讀取器獲取鎖定。請參閱 RWMutex 類型的文檔。
func (rw *RWMutex) RLocker() Locker
RLocker 通過調(diào)用 rw.RLock 和 rw.RUnlock 返回一個實現(xiàn) Lock 和 Unlock 方法的 Locker 接口。
func (rw *RWMutex) RUnlock()
RUnlock 撤銷了一次單獨的 RLock 調(diào)用; 它不會影響其他同時閱讀。如果 rw 沒有被鎖定讀入 RUnlock,那么這是一個運行時錯誤。
func (rw *RWMutex) Unlock()
Unlock 解鎖 rw 寫入。如果 rw 沒有被鎖定寫入Unlock,那么這是一個運行時錯誤。
與 Mutexes 一樣,鎖定的 RWMutex 與特定的 goroutine 沒有關聯(lián)。一個例程可以 RLock (鎖定)一個 RWMutex ,然后安排另一個例程來 RUnlock (解鎖)它。
WaitGroup 等待一系列 goroutine 完成。主要的 goroutine 調(diào)用 Add 來設置要等待的 goroutines 的數(shù)量。然后,每個 goroutines 運行并在完成時調(diào)用完成。同時,Wait 可以用來阻塞,直到所有的 goroutines 都完成。
首次使用后,不得復制 WaitGroup 。
type WaitGroup struct { // contains filtered or unexported fields}
本示例同時提取多個 URL ,使用 WaitGroup 進行阻塞,直到所有提取完成。
編碼:
var wg sync.WaitGroupvar urls = []string{ "http://www.golang.org/", "http://www.google.com/", "http://www.somestupidname.com/",}for _, url := range urls { // Increment the WaitGroup counter. wg.Add(1) // Launch a goroutine to fetch the URL. go func(url string) { // Decrement the counter when the goroutine completes. defer wg.Done() // Fetch the URL. http.Get(url) }(url)}// Wait for all HTTP fetches to complete.wg.Wait()
func (wg *WaitGroup) Add(delta int)
添加向 WaitGroup 計數(shù)器添加可能為負數(shù)的增量。如果計數(shù)器變?yōu)榱?,則等待的所有程序都被釋放。如果計數(shù)器變?yōu)樨撝担執(zhí)砑咏K止。
請注意,在計數(shù)器為零時發(fā)生的積極增量的調(diào)用必須發(fā)生在 Wait. Calls 之前??梢栽谌魏螘r候發(fā)生帶有負三角形的調(diào)用,或者在計數(shù)器大于零時開始的具有正三角形的調(diào)用。通常這意味著添加的調(diào)用應該在創(chuàng)建 goroutine 或其他要等待的事件的語句之前執(zhí)行。如果 WaitGroup 被重新使用以等待多個獨立的事件集合,則在所有先前的等待調(diào)用已經(jīng)返回之后,必須發(fā)生新的添加調(diào)用。請參閱 WaitGroup 示例。
func (wg *WaitGroup) Done()
完成將 WaitGroup 計數(shù)器遞減1。
func (wg *WaitGroup) Wait()
Wait 塊,直到 WaitGroup 計數(shù)器為零。
名稱 | 概要 |
---|
| .. |
| atomic| 打包 atomic 提供了用于實現(xiàn)同步算法的低級 atomic 內(nèi)存原語。|