?
? ????? PHP ??? ???? ??? ?? ??
import "sync"
概觀
索引
示例
子目錄
程序包 sync 提供基本的同步原語,如互斥鎖。除了 Once 和 WaitGroup 類型之外,大多數(shù)類型都是供低級(jí)庫例程使用的。通過 Channel 和溝通可以更好地完成更高級(jí)別的同步。
包含此程序包中定義的類型的值不應(yīng)被復(fù)制。
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 實(shí)現(xiàn)了一個(gè)條件變量,用于等待或通告事件發(fā)生的 goroutine 的集合點(diǎn)。
每個(gè) Cond 都有一個(gè)關(guān)聯(lián)的 Locker L (通常是 * Mutex 或 * RWMutex ),在更改條件和調(diào)用 Wait 方法時(shí)必須保持該 L。
首次使用后不得復(fù)制 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 返回一個(gè)帶有 Locker L 的新 Cond 。
func (c *Cond) Broadcast()
廣播喚醒等待的所有 goroutines c 。
在通話過程中,主叫方可以允許但不是必需的。
func (c *Cond) Signal()
如果有任何信號(hào),信號(hào)喚醒一個(gè)等待在 c 上的 goroutine 。
在調(diào)用過程中,調(diào)用方可以允許但不是必需的。
func (c *Cond) Wait()
等待原子的解鎖 c.L 并暫停執(zhí)行調(diào)用的 goroutine 。在稍后恢復(fù)執(zhí)行后, Wait 在返回之前鎖定 c.L 。與其他系統(tǒng)不同,除非廣播或信號(hào)喚醒,否則 Wait 不能返回。
因?yàn)楫?dāng) Wait 第一次恢復(fù)時(shí) c.L 沒有被鎖定,所以當(dāng) Wait 返回時(shí),調(diào)用者通常不能認(rèn)為條件為真。相反,調(diào)用者應(yīng)該等待一個(gè)循環(huán):
c.L.Lock()for !condition() { c.Wait()}... make use of condition ...c.L.Unlock()
Locker 表示可以鎖定和解鎖的物體。
type Locker interface { Lock() Unlock()}
Map 是一個(gè)并發(fā)映射,包含分期恒定時(shí)間加載,存儲(chǔ)和刪除。多個(gè) goroutines 同時(shí)調(diào)用 Map 的方法是安全的。
它針對(duì)并發(fā)循環(huán)進(jìn)行了優(yōu)化,使用的密鑰隨時(shí)間保持穩(wěn)定,并且只有少數(shù)穩(wěn)態(tài)存儲(chǔ),或者每個(gè)密鑰存儲(chǔ)在一個(gè) goroutine 中。
對(duì)于不共享這些屬性的用例,與使用讀寫互斥鎖配對(duì)的普通映射相比,它可能具有可比較或更差的性能以及更差的類型安全性。
零映射有效且為空。
首次使用后不得復(fù)制 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)
加載返回鍵映射中存儲(chǔ)的值,如果沒有值,則返回零。ok 的結(jié)果表示在地圖中是否找到了值。
func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool)
LoadOrStore 返回鍵的現(xiàn)有值(如果存在)。否則,它存儲(chǔ)并返回給定的值。如果加載的值加載結(jié)果為 true ,如果存儲(chǔ)則加載為 false 。
func (m *Map) Range(f func(key, value interface{}) bool)
范圍按順序?yàn)榈貓D中存在的每個(gè)鍵和值調(diào)用 f 。如果 f 返回 false ,范圍將停止迭代。
范圍不一定對(duì)應(yīng)于 Map 內(nèi)容的任何一致快照:不會(huì)有多次訪問密鑰,但如果同時(shí)存儲(chǔ)或刪除任何密鑰的值,則范圍可能反映該范圍內(nèi)任何點(diǎn)的該密鑰的任何映射調(diào)用。
范圍可能是 O(N) 與映射中的元素?cái)?shù)量,即使f在常數(shù)調(diào)用后返回 false 也是如此。
func (m *Map) Store(key, value interface{})
存儲(chǔ)設(shè)置密鑰的值。
Mutex 是互斥鎖。Mutex 的零值是一個(gè)解鎖的互斥鎖。
第一次使用后不得復(fù)制 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 未鎖定進(jìn)入解鎖,則為運(yùn)行時(shí)錯(cuò)誤。
鎖定的互斥鎖與特定的 goroutine 沒有關(guān)聯(lián)。允許一個(gè) goroutine 鎖定一個(gè) Mutex ,然后安排另一個(gè) goroutine 來解鎖它。
一旦一個(gè)對(duì)象會(huì)執(zhí)行一個(gè)動(dòng)作。
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())
當(dāng)且僅當(dāng)?shù)谝淮螢檫@個(gè) Once 實(shí)例調(diào)用 Do時(shí),才調(diào)用函數(shù) f 。換句話說,給出
var once Once
如果一次 .Do(f) 被多次調(diào)用,只有第一次調(diào)用會(huì)調(diào)用f,即使 f 在每次調(diào)用中都有不同的值。一個(gè)新的實(shí)例需要執(zhí)行每個(gè)函數(shù)。
Do 是用于初始化的,只能運(yùn)行一次。由于 f 是 niladic,因此可能需要使用函數(shù)文字來捕獲由 Do 調(diào)用的函數(shù)的參數(shù):
config.once.Do(func() { config.init(filename) })
由于沒有對(duì) Do 的調(diào)用返回,直到對(duì) f 的一次調(diào)用返回,如果 f 導(dǎo)致 Do 被調(diào)用,它將會(huì)死鎖。
如果 f 終止, Do 認(rèn)為它已經(jīng)返回; 未來的調(diào)用返回而不調(diào)用 f 。
Pool 是一組可以單獨(dú)保存和檢索的臨時(shí)對(duì)象。
存儲(chǔ)在 Pool 中的任何項(xiàng)目可能會(huì)隨時(shí)自動(dòng)刪除,而無需通知。如果 Pool 在這種情況發(fā)生時(shí)只有唯一的引用,則該項(xiàng)可能會(huì)被釋放。
Pool 可以同時(shí)用于多個(gè) goroutine 。
Pool 的目的是緩存已分配但未使用的項(xiàng)目以備后用,以減輕垃圾收集器的壓力。也就是說,它可以輕松構(gòu)建高效,線程安全的免費(fèi)列表。但是,它不適用于所有不受限制的列表。
Pool 的適當(dāng)使用是管理一組臨時(shí)項(xiàng)目,這些臨時(shí)項(xiàng)目在一個(gè)程序包的并發(fā)獨(dú)立客戶端之間悄悄共享并可能被重用。Pool 提供了一種方法來緩解跨多個(gè)客戶端的分配開銷。
fmt 包中有一個(gè)很好地使用 Pool 的例子,它維護(hù)一個(gè)動(dòng)態(tài)大小的臨時(shí)輸出緩沖區(qū)存儲(chǔ)區(qū)。商店在負(fù)載下(當(dāng)許多 goroutines 正在活動(dòng)時(shí))縮小,靜止時(shí)縮小。
另一方面,作為短期對(duì)象的一部分而維護(hù)的空閑列表對(duì)于 Pool 來說并不適合,因?yàn)樵谠搱?chǎng)景中開銷不能很好地分?jǐn)?。讓這些對(duì)象實(shí)現(xiàn)自己的不受限制的列表會(huì)更高效。
首次使用后不得復(fù)制 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 中選擇一個(gè)任意項(xiàng)目,將其從池中刪除,并將其返回給調(diào)用者。獲取可能會(huì)選擇忽略 Pool 并將其視為空。調(diào)用者不應(yīng)承擔(dān)傳遞給 Put 的值與 Get 返回的值之間的任何關(guān)系。
如果 Get 以其他方式返回 nil ,并且 p.New 不為零,則 Get 返回調(diào)用 p.New 的結(jié)果。
func (p *Pool) Put(x interface{})
Put 將 x 添加到 Pool 中。
RWMutex 是讀寫器互斥鎖。該鎖可以由任意數(shù)量的讀者或單個(gè)作者持有。 RWMutex 的零值是一個(gè)解鎖的互斥鎖。
首次使用后,RWMutex 不得被復(fù)制。
如果一個(gè) goroutine 持有一個(gè) RWMutex 用于讀取,另一個(gè) goroutine 可能調(diào)用 Lock ,那么在最初的讀取鎖定被釋放之前,沒有 goroutine 應(yīng)該期望能夠獲得讀取鎖定。特別是,這禁止了遞歸讀取鎖定。這是為了確保鎖最終可用; 被鎖定的鎖定呼叫不包括新讀取器獲取鎖定。
type RWMutex struct { // contains filtered or unexported fields}
func (rw *RWMutex) Lock()
Lock 鎖定 rw 寫入。如果鎖已被鎖定以進(jìn)行讀取或?qū)懭?,則 Lock 塊直到鎖可用。
func (rw *RWMutex) RLock()
RLock 鎖定 rw 閱讀。
它不應(yīng)該用于遞歸讀鎖定;被鎖定的鎖定呼叫不包括新讀取器獲取鎖定。請(qǐng)參閱 RWMutex 類型的文檔。
func (rw *RWMutex) RLocker() Locker
RLocker 通過調(diào)用 rw.RLock 和 rw.RUnlock 返回一個(gè)實(shí)現(xiàn) Lock 和 Unlock 方法的 Locker 接口。
func (rw *RWMutex) RUnlock()
RUnlock 撤銷了一次單獨(dú)的 RLock 調(diào)用; 它不會(huì)影響其他同時(shí)閱讀。如果 rw 沒有被鎖定讀入 RUnlock,那么這是一個(gè)運(yùn)行時(shí)錯(cuò)誤。
func (rw *RWMutex) Unlock()
Unlock 解鎖 rw 寫入。如果 rw 沒有被鎖定寫入U(xiǎn)nlock,那么這是一個(gè)運(yùn)行時(shí)錯(cuò)誤。
與 Mutexes 一樣,鎖定的 RWMutex 與特定的 goroutine 沒有關(guān)聯(lián)。一個(gè)例程可以 RLock (鎖定)一個(gè) RWMutex ,然后安排另一個(gè)例程來 RUnlock (解鎖)它。
WaitGroup 等待一系列 goroutine 完成。主要的 goroutine 調(diào)用 Add 來設(shè)置要等待的 goroutines 的數(shù)量。然后,每個(gè) goroutines 運(yùn)行并在完成時(shí)調(diào)用完成。同時(shí),Wait 可以用來阻塞,直到所有的 goroutines 都完成。
首次使用后,不得復(fù)制 WaitGroup 。
type WaitGroup struct { // contains filtered or unexported fields}
本示例同時(shí)提取多個(gè) URL ,使用 WaitGroup 進(jìn)行阻塞,直到所有提取完成。
編碼:
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 計(jì)數(shù)器添加可能為負(fù)數(shù)的增量。如果計(jì)數(shù)器變?yōu)榱?,則等待的所有程序都被釋放。如果計(jì)數(shù)器變?yōu)樨?fù)值,請(qǐng)?zhí)砑咏K止。
請(qǐng)注意,在計(jì)數(shù)器為零時(shí)發(fā)生的積極增量的調(diào)用必須發(fā)生在 Wait. Calls 之前??梢栽谌魏螘r(shí)候發(fā)生帶有負(fù)三角形的調(diào)用,或者在計(jì)數(shù)器大于零時(shí)開始的具有正三角形的調(diào)用。通常這意味著添加的調(diào)用應(yīng)該在創(chuàng)建 goroutine 或其他要等待的事件的語句之前執(zhí)行。如果 WaitGroup 被重新使用以等待多個(gè)獨(dú)立的事件集合,則在所有先前的等待調(diào)用已經(jīng)返回之后,必須發(fā)生新的添加調(diào)用。請(qǐng)參閱 WaitGroup 示例。
func (wg *WaitGroup) Done()
完成將 WaitGroup 計(jì)數(shù)器遞減1。
func (wg *WaitGroup) Wait()
Wait 塊,直到 WaitGroup 計(jì)數(shù)器為零。
名稱 | 概要 |
---|
| .. |
| atomic| 打包 atomic 提供了用于實(shí)現(xiàn)同步算法的低級(jí) atomic 內(nèi)存原語。|