# package sync
`import "sync"`
sync包提供了基本的同步基元,如互斥鎖。除了Once和WaitGroup類型,大部分都是適用于低水平程序線程,高水平的同步使用channel通信更好一些。
本包的類型的值不應被拷貝。
## Index
* [type Locker](#Locker)
* [type Once](#Once)
* [func (o \*Once) Do(f func())](#Once.Do)
* [type Mutex](#Mutex)
* [func (m \*Mutex) Lock()](#Mutex.Lock)
* [func (m \*Mutex) Unlock()](#Mutex.Unlock)
* [type RWMutex](#RWMutex)
* [func (rw \*RWMutex) Lock()](#RWMutex.Lock)
* [func (rw \*RWMutex) Unlock()](#RWMutex.Unlock)
* [func (rw \*RWMutex) RLock()](#RWMutex.RLock)
* [func (rw \*RWMutex) RUnlock()](#RWMutex.RUnlock)
* [func (rw \*RWMutex) RLocker() Locker](#RWMutex.RLocker)
* [type Cond](#Cond)
* [func NewCond(l Locker) \*Cond](#NewCond)
* [func (c \*Cond) Broadcast()](#Cond.Broadcast)
* [func (c \*Cond) Signal()](#Cond.Signal)
* [func (c \*Cond) Wait()](#Cond.Wait)
* [type WaitGroup](#WaitGroup)
* [func (wg \*WaitGroup) Add(delta int)](#WaitGroup.Add)
* [func (wg \*WaitGroup) Done()](#WaitGroup.Done)
* [func (wg \*WaitGroup) Wait()](#WaitGroup.Wait)
* [type Pool](#Pool)
* [func (p \*Pool) Get() interface{}](#Pool.Get)
* [func (p \*Pool) Put(x interface{})](#Pool.Put)
### Examples
* [Once](#example-Once)
* [WaitGroup](#example-WaitGroup)
## type [Locker](https://github.com/golang/go/blob/master/src/sync/mutex.go#L27 "View Source")
```
type Locker interface {
Lock()
Unlock()
}
```
Locker接口代表一個可以加鎖和解鎖的對象。
## type [Once](https://github.com/golang/go/blob/master/src/sync/once.go#L12 "View Source")
```
type Once struct {
// 包含隱藏或非導出字段
}
```
Once是只執行一次動作的對象。
Example
```
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
}
```
Output:
```
Only once
```
### func (\*Once) [Do](https://github.com/golang/go/blob/master/src/sync/once.go#L32 "View Source")
```
func (o *Once) Do(f func())
```
Do方法當且僅當第一次被調用時才執行函數f。換句話說,給定變量:
```
var once Once
```
如果once.Do(f)被多次調用,只有第一次調用會執行f,即使f每次調用Do 提供的f值不同。需要給每個要執行僅一次的函數都建立一個Once類型的實例。
Do用于必須剛好運行一次的初始化。因為f是沒有參數的,因此可能需要使用閉包來提供給Do方法調用:
```
config.once.Do(func() { config.init(filename) })
```
因為只有f返回后Do方法才會返回,f若引起了Do的調用,會導致死鎖。
## type [Mutex](https://github.com/golang/go/blob/master/src/sync/mutex.go#L21 "View Source")
```
type Mutex struct {
// 包含隱藏或非導出字段
}
```
Mutex是一個互斥鎖,可以創建為其他結構體的字段;零值為解鎖狀態。Mutex類型的鎖和線程無關,可以由不同的線程加鎖和解鎖。
### func (\*Mutex) [Lock](https://github.com/golang/go/blob/master/src/sync/mutex.go#L41 "View Source")
```
func (m *Mutex) Lock()
```
Lock方法鎖住m,如果m已經加鎖,則阻塞直到m解鎖。
### func (\*Mutex) [Unlock](https://github.com/golang/go/blob/master/src/sync/mutex.go#L82 "View Source")
```
func (m *Mutex) Unlock()
```
Unlock方法解鎖m,如果m未加鎖會導致運行時錯誤。鎖和線程無關,可以由不同的線程加鎖和解鎖。
## type [RWMutex](https://github.com/golang/go/blob/master/src/sync/rwmutex.go#L18 "View Source")
```
type RWMutex struct {
// 包含隱藏或非導出字段
}
```
RWMutex是讀寫互斥鎖。該鎖可以被同時多個讀取者持有或唯一個寫入者持有。RWMutex可以創建為其他結構體的字段;零值為解鎖狀態。RWMutex類型的鎖也和線程無關,可以由不同的線程加讀取鎖/寫入和解讀取鎖/寫入鎖。
### func (\*RWMutex) [Lock](https://github.com/golang/go/blob/master/src/sync/rwmutex.go#L72 "View Source")
```
func (rw *RWMutex) Lock()
```
Lock方法將rw鎖定為寫入狀態,禁止其他線程讀取或者寫入。
### func (\*RWMutex) [Unlock](https://github.com/golang/go/blob/master/src/sync/rwmutex.go#L98 "View Source")
```
func (rw *RWMutex) Unlock()
```
Unlock方法解除rw的寫入鎖狀態,如果m未加寫入鎖會導致運行時錯誤。
### func (\*RWMutex) [RLock](https://github.com/golang/go/blob/master/src/sync/rwmutex.go#L29 "View Source")
```
func (rw *RWMutex) RLock()
```
RLock方法將rw鎖定為讀取狀態,禁止其他線程寫入,但不禁止讀取。
### func (\*RWMutex) [RUnlock](https://github.com/golang/go/blob/master/src/sync/rwmutex.go#L48 "View Source")
```
func (rw *RWMutex) RUnlock()
```
Runlock方法解除rw的讀取鎖狀態,如果m未加讀取鎖會導致運行時錯誤。
### func (\*RWMutex) [RLocker](https://github.com/golang/go/blob/master/src/sync/rwmutex.go#L121 "View Source")
```
func (rw *RWMutex) RLocker() Locker
```
Rlocker方法返回一個互斥鎖,通過調用rw.Rlock和rw.Runlock實現了Locker接口。
## type [Cond](https://github.com/golang/go/blob/master/src/sync/cond.go#L22 "View Source")
```
type Cond struct {
// 在觀測或更改條件時L會凍結
L Locker
// 包含隱藏或非導出字段
}
```
Cond實現了一個條件變量,一個線程集合地,供線程等待或者宣布某事件的發生。
每個Cond實例都有一個相關的鎖(一般是\*Mutex或\*RWMutex類型的值),它必須在改變條件時或者調用Wait方法時保持鎖定。Cond可以創建為其他結構體的字段,Cond在開始使用后不能被拷貝。
### func [NewCond](https://github.com/golang/go/blob/master/src/sync/cond.go#L32 "View Source")
```
func NewCond(l Locker) *Cond
```
使用鎖l創建一個\*Cond。
### func (\*Cond) [Broadcast](https://github.com/golang/go/blob/master/src/sync/cond.go#L78 "View Source")
```
func (c *Cond) Broadcast()
```
Broadcast喚醒所有等待c的線程。調用者在調用本方法時,建議(但并非必須)保持c.L的鎖定。
### func (\*Cond) [Signal](https://github.com/golang/go/blob/master/src/sync/cond.go#L70 "View Source")
```
func (c *Cond) Signal()
```
Signal喚醒等待c的一個線程(如果存在)。調用者在調用本方法時,建議(但并非必須)保持c.L的鎖定。
### func (\*Cond) [Wait](https://github.com/golang/go/blob/master/src/sync/cond.go#L52 "View Source")
```
func (c *Cond) Wait()
```
Wait自行解鎖c.L并阻塞當前線程,在之后線程恢復執行時,Wait方法會在返回前鎖定c.L。和其他系統不同,Wait除非被Broadcast或者Signal喚醒,不會主動返回。
因為線程中Wait方法是第一個恢復執行的,而此時c.L未加鎖。調用者不應假設Wait恢復時條件已滿足,相反,調用者應在循環中等待:
```
c.L.Lock()
for !condition() {
c.Wait()
}
... make use of condition ...
c.L.Unlock()
```
## type [WaitGroup](https://github.com/golang/go/blob/master/src/sync/waitgroup.go#L17 "View Source")
```
type WaitGroup struct {
// 包含隱藏或非導出字段
}
```
WaitGroup用于等待一組線程的結束。父線程調用Add方法來設定應等待的線程的數量。每個被等待的線程在結束時應調用Done方法。同時,主線程里可以調用Wait方法阻塞至所有線程結束。
Example
```
var wg sync.WaitGroup
var 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 (\*WaitGroup) [Add](https://github.com/golang/go/blob/master/src/sync/waitgroup.go#L44 "View Source")
```
func (wg *WaitGroup) Add(delta int)
```
Add方法向內部計數加上delta,delta可以是負數;如果內部計數器變為0,Wait方法阻塞等待的所有線程都會釋放,如果計數器小于0,方法panic。注意Add加上正數的調用應在Wait之前,否則Wait可能只會等待很少的線程。一般來說本方法應在創建新的線程或者其他應等待的事件之前調用。
### func (\*WaitGroup) [Done](https://github.com/golang/go/blob/master/src/sync/waitgroup.go#L81 "View Source")
```
func (wg *WaitGroup) Done()
```
Done方法減少WaitGroup計數器的值,應在線程的最后執行。
### func (\*WaitGroup) [Wait](https://github.com/golang/go/blob/master/src/sync/waitgroup.go#L86 "View Source")
```
func (wg *WaitGroup) Wait()
```
Wait方法阻塞直到WaitGroup計數器減為0。
## type [Pool](https://github.com/golang/go/blob/master/src/sync/pool.go#L42 "View Source")
```
type Pool struct {
// 可選參數New指定一個函數在Get方法可能返回nil時來生成一個值
// 該參數不能在調用Get方法時被修改
New func() interface{}
// 包含隱藏或非導出字段
}
```
Pool是一個可以分別存取的臨時對象的集合。
Pool中保存的任何item都可能隨時不做通告的釋放掉。如果Pool持有該對象的唯一引用,這個item就可能被回收。
Pool可以安全的被多個線程同時使用。
Pool的目的是緩存申請但未使用的item用于之后的重用,以減輕GC的壓力。也就是說,讓創建高效而線程安全的空閑列表更容易。但Pool并不適用于所有空閑列表。
Pool的合理用法是用于管理一組靜靜的被多個獨立并發線程共享并可能重用的臨時item。Pool提供了讓多個線程分攤內存申請消耗的方法。
Pool的一個好例子在fmt包里。該Pool維護一個動態大小的臨時輸出緩存倉庫。該倉庫會在過載(許多線程活躍的打印時)增大,在沉寂時縮小。
另一方面,管理著短壽命對象的空閑列表不適合使用Pool,因為這種情況下內存申請消耗不能很好的分配。這時應該由這些對象自己實現空閑列表。
### func (\*Pool) [Get](https://github.com/golang/go/blob/master/src/sync/pool.go#L93 "View Source")
```
func (p *Pool) Get() interface{}
```
Get方法從池中選擇任意一個item,刪除其在池中的引用計數,并提供給調用者。Get方法也可能選擇無視內存池,將其當作空的。調用者不應認為Get的返回這和傳遞給Put的值之間有任何關系。
假使Get方法沒有取得item:如p.New非nil,Get返回調用p.New的結果;否則返回nil。
### func (\*Pool) [Put](https://github.com/golang/go/blob/master/src/sync/pool.go#L61 "View Source")
```
func (p *Pool) Put(x interface{})
```
Put方法將x放入池中。
- 庫
- package achive
- package tar
- package zip
- package bufio
- package builtin
- package bytes
- package compress
- package bzip2
- package flate
- package gzip
- package lzw
- package zlib
- package container
- package heap
- package list
- package ring
- package crypto
- package aes
- package cipher
- package des
- package dsa
- package ecdsa
- package elliptic
- package hmac
- package md5
- package rand
- package rc4
- package rsa
- package sha1
- package sha256
- package sha512
- package subtle
- package tls
- package x509
- package pkix
- package database
- package sql
- package driver
- package encoding
- package ascii85
- package asn1
- package base32
- package base64
- package binary
- package csv
- package gob
- package hex
- package json
- package pem
- package xml
- package errors
- package expvar
- package flag
- package fmt
- package go
- package doc
- package format
- package parser
- package printer
- package hash
- package adler32
- package crc32
- package crc64
- package fnv
- package html
- package template
- package image
- package color
- package palette
- package draw
- package gif
- package jpeg
- package png
- package index
- package suffixarray
- package io
- package ioutil
- package log
- package syslog
- package math
- package big
- package cmplx
- package rand
- package mime
- package multipart
- package net
- package http
- package cgi
- package cookiejar
- package fcgi
- package httptest
- package httputil
- package pprof
- package mail
- package rpc
- package jsonrpc
- package smtp
- package textproto
- package url
- package os
- package exec
- package signal
- package user
- package path
- package filepath
- package reflect
- package regexp
- package runtime
- package cgo
- package debug
- package pprof
- package race
- package sort
- package strconv
- package strings
- package sync
- package atomic
- package text
- package scanner
- package tabwriter
- package template
- package time
- package unicode
- package utf16
- package utf8
- package unsafe