版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013862108/article/details/87886943
WaitGroup
func main() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done() //我们向WaitGroup 表明我们已经退出了
fmt.Println("1st goroutine sleeping...")
time.Sleep(1)
}()
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("2nd goroutine sleeping...")
time.Sleep(2)
}()
wg.Wait() //这将阻塞main goroutine, 直到所有goroutine 表明它们已经退出。
fmt.Println("All goroutines complete.")
}
//2nd goroutine sleeping... //1st goroutine sleeping... //All goroutines complete.
可以将WaitGroup 视为一个并发-安全的计数器;通过传入的整数执行add 方法增加计数器的增量,并调用Done方法对计数器进行递减。Wait阻塞,直到 计数器为零。 注意,添加的调用(wg.Add(1)) 写在 goroutine之外完成的。如果写在goroutine 之内,就会引入一种竞争条件,因为不确定goroutine 何时会被调度,
WaitGroup来追踪一组goroutine :
func main(){
hello := func(wg *sync.WaitGroup, id int) {
defer wg.Done()
fmt.Printf("hello from %v!\n", id)
}
const numGreeters = 5
var wg sync.WaitGroup
wg.Add(numGreeters)
for i:= 0; i< numGreeters; i++{
go hello(&wg, i+1)
}
wg.Wait()
}
//hello from 2!
//hello from 5!
//hello from 3!
//hello from 1!
//hello from 4!
互斥锁 : Mutex 是 "互斥"的意思, 是保护程序中临界区的一种方式。Mutex 提供了一种安全的方式来表示对这些 共享资源(临界区) 的独占访问 为了访问/使用 一个资源: channel 通过通信共享内存, 而Mutex 通过开发人员的约定 同步访问 共享内存
func main() {
var count int
var lock sync.Mutex
increment := func() {
lock.Lock()
defer lock.Unlock()
count++
fmt.Printf("Incrementing: %d\n",count)
}
decrement := func() {
lock.Lock()
defer lock.Unlock()
count--
fmt.Printf("Decrementing:%d\n", count)
}
//增量
var arithmetic sync.WaitGroup
for i:=0; i<=100; i++{ //5
arithmetic.Add(1)
go func() {
defer arithmetic.Done()
increment()
}()
}
//减量
for i:=0; i <= 100; i++{ //5
arithmetic.Add(1)
go func() {
defer arithmetic.Done()
decrement()
}()
}
arithmetic.Wait()
fmt.Println("Arithmetic complete")
fmt.Printf("count's value is :%d\n", count)
}
/**
如果不加锁: 某次运行最后 Incrementing:3 ; count's value is :-1
加锁,总是能保证 Incrementing:0
我们总是在defer语句中调用 Unlock。
*/
读写锁 :?? todo;
//通常建议使用RWMutex, 而不是Mutex, 因为它在逻辑上更加合理