PHP中高级工程师面试重点讲解视频课程
Go快速入门浅显易懂视频教程-基础篇
Go快速入门浅显易懂视频教程-中级篇
go的sync包的使用详解1-日常实战总结6
阅读:361 分享次数:0

这里是讲sync整个包的使用,但是会排出sync.pool的使用,sync.pool为啥单独拿出来讲,是因为sync.pool在高并发以及重复利用的变量使用中有很好的效果。sync包是业务中最常用的类库能排名前三,学会sync包的使用是很有必要的。

下面我们看一下sync包中sync,WaitGroup其他功能。

sync.WaitGroup:作为多协程之间同步的一种机制,用于等待一组线程的结束。
主线程调用Add方法来设定应等待的线程的数量,同时主线程里可以调用Wait方法阻塞至所有线程结束。
每个被等待的子线程在结束时应调用Done方法。

下面我们来看一个例子:

package main

import (
  "fmt"
  "sync"
  "time"
  "math/rand"
)

func main() {
  //这里是初始化
  wg := new(sync.WaitGroup)
  //这里是添加可能出现的协程数,必须在主线程执行。
  wg.Add(4)
  //这里使用go func 表示协程调用
  go test(wg)
  go test(wg)
  go test(wg)
  go test(wg)
  //这里是主线程wg组等待
  wg.Wait()
  fmt.Println("over")
}

func test(w *sync.WaitGroup) {
  time.Sleep(time.Second * 2)
  fmt.Println(time.Now())
  fmt.Println(rand.Int())
  w.Done()
}

看一下返回结果:

2019-11-23 14:38:46.1110006 +0800 CST m=+2.013265501
5577006791947779410
2019-11-23 14:38:46.1110006 +0800 CST m=+2.013265501
8674665223082153551
2019-11-23 14:38:46.1110006 +0800 CST m=+2.013265501
6129484611666145821
2019-11-23 14:38:46.1110006 +0800 CST m=+2.013265501
4037200794235010051
over

下面我们看一下Mutex(互斥锁)和RWMutex(读写锁)的使用

下面的代码的程序主要是通过多个协程并发incr和decr让变量c按照顺序增加和减少,来验证互斥锁的使用。

package main

import (
  "sync"
  "fmt"
  "time"
)

var l = new(sync.Mutex)

func main() {
  //首先看一下Mutex(互斥锁)和RWMutex(读写锁)
  //初始化c
  c := 0
  //增加一个全局锁
  lock := new(sync.Mutex)
  incr := func() {
    lock.Lock()         // 1
    defer lock.Unlock() // 2
    c++
    fmt.Printf("incr: %d\n", c)
  }
  decr := func() {
    lock.Lock()         // 1
    defer lock.Unlock() // 2
    c--
    fmt.Printf("decr: %d\n", c)
  }
  //用waitgroup 让主线程等待子线程的结果返回,多个协程调用incr或者decr方法来对变量c进行增加和减少。
  w := new(sync.WaitGroup)
  for i := 0; i <= 3; i++ {
    w.Add(1)
    go func() {
      defer w.Done()
      incr()
    }()
  }
  for i := 0; i <= 3; i++ {
    w.Add(1)
    go func() {
      defer w.Done()
        decr()
      }()
  }
  w.Wait()
}

下面这个是结果,结果是按照每次只增加1或者减少1,表示互斥锁的使用得到验证。实际业务中我们主要是map,contain/list等线程不安全的数据类型才使用上锁。

incr: 1
decr: 0
decr: -1
decr: -2
decr: -3
incr: -2
incr: -1
incr: 0


感觉本站内容不错,读后有收获?