1. 互斥量
import "sync"
var mutex sync.Mutex
mutex.Lock()
// ...
mutex.Unlock()
2. 读写锁
import "sync"
var mutex sync.RWMutex
读者:
mutex.RLock()
// ...
mutex.RUnlock()
写者:
mutex.Lock()
// ...
mutex.Unlock()
3. 条件变量
import "sync"
var mutex sync.Mutex
var cond = sync.NewCond(&mutex)
等待者:
cond.L.Lock()
for !condition-is-met {
cond.Wait()
}
// ...
cond.L.Unlock()
唤醒者:
cond.L.Lock()
// ...
cond.L.Unlock()
cond.Signal() // 或 cond.Broadcast()
4. once
即使在多个 goroutine 中调用,也只会执行某个动作一次。
package main
import (
"fmt"
"sync"
"time"
)
func action() {
fmt.Println("hello, world!")
}
func main() {
var once sync.Once
for i := 0; i < 10; i++ {
go func() {
once.Do(action)
}()
}
time.Sleep(time.Second * 2)
}
输出:
hello, world!
5. 等待组
package main
import (
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func worker() {
time.Sleep(time.Second)
wg.Done()
}
func main() {
n := 5
wg.Add(n)
for i := 0; i < n; i++ {
go worker()
}
wg.Wait()
fmt.Println("done!")
}
wg.Add(n)
:修改 WaitGroup 计数器。wg.Done()
:将 WaitGroup 计数器减一。wg.Wait()
:等待 WaitGroup 计数器变为 0。