sync
WaitGroup
如下例子,将不会输出任何东西。因为main goroutine立即退出,因此两个goroutine都没有来得及执行。
package main
import (
"fmt"
)
func main() {
go func() {
fmt.Println(1)
}()
go func() {
fmt.Println(2)
}()
}
为了得到两个goroutine输出,可以在main中通过time.Sleep
来延迟程序结束:
package main
import (
"fmt"
"time"
)
func main() {
go func() {
fmt.Println(1)
}()
go func() {
fmt.Println(2)
}()
time.Sleep(2 * time.Second)
}
也可以通过channel
的方式:
package main
import (
"fmt"
)
func main() {
c := make(chan struct{})
go func() {
fmt.Println(1)
c <- struct{}{}
}()
go func() {
fmt.Println(2)
c <- struct{}{}
}()
for i := 0; i < 2; i++ {
<-c
}
}
不过,更方便的是通过sync.WaitGroup
来实现:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(2)
go func() {
fmt.Println(1)
wg.Done()
}()
go func() {
fmt.Println(2)
wg.Done()
}()
wg.Wait()
}
WaitGroup
可以等待一系列goroutine的执行完成。在main goroutine中通过Add
方法指定等待的个数,在每个goroutine中调用Done
方法标记该goroutine执行完成。Wait
方法会等待,直到所有的goroutine执行结束。
Locker
Locker
是一个接口,有Lock
和Unlock
方法:
type Locker interface {
Lock()
Unlock()
}
Mutex
Mutex
提供了互斥锁的机制。例如:
var mutex sync.Mutex
mutex.Lock()
// ...
mutex.Unlock()
也可以通过defer
的写法,例如:
var mutex sync.Mutex
func fn() {
mutex.Lock()
defer mutex.Unlock()
// ...
}
RWMutex
RWMutex
同时提供了共享锁和互斥锁的机制。其Lock
和Unlock
依然是互斥锁的操作,另外RLock
和RUnlock
是共享锁。通过其Locker
方法可以获取锁对象。