golang/go语言sync同步包中的WaitGroup等待组Mutex互斥锁和RWMutex读写锁

Posted 棉花糖灬

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang/go语言sync同步包中的WaitGroup等待组Mutex互斥锁和RWMutex读写锁相关的知识,希望对你有一定的参考价值。

1. WaitGroup等待组

WaitGroup通过一个计数器counter来让主协程在还有子协程运行的时候进行等待

  • wg.Add(num)函数可以让counter的值加上具体数值
  • wg.Wait()函数可以让主协程进入阻塞状态
  • wg. Done()函数可以让counter的值减一,相当于Add(-1)
package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

func main() 
	wg.Add(2)
	go func1()
	go func2()
	fmt.Println("WaitGroup进入阻塞...")
	wg.Wait()
	fmt.Println("WaitGroup结束阻塞...")


func func1() 
	for i := 0; i < 10; i++ 
		fmt.Println("func1执行... ", i)
	
	wg.Done()


func func2() 
	defer wg.Done()
	for i := 0; i < 10; i++ 
		fmt.Println("\\tfunc2执行... ", i)
	

2. Mutex互斥锁

通过给临界资源加锁,以让多个协程互斥访问临界资源。

  • mutex.Lock()函数给资源加锁
  • mutex.Unlock()函数给资源解锁
package main

import (
   "fmt"
   "sync"
)

var ticktsNum = 10
var wg sync.WaitGroup
var mutex sync.Mutex

func main() 
   wg.Add(4)
   go saleTickts(1)
   go saleTickts(2)
   go saleTickts(3)
   go saleTickts(4)
   wg.Wait()


func saleTickts(window int) 
   defer wg.Done()
   for 
      mutex.Lock()
      if ticktsNum > 0 
         fmt.Printf("窗口%d售卖,剩余票%d张\\n", window, ticktsNum)
         ticktsNum--
         mutex.Unlock()
       else 
         fmt.Printf("窗口%d售卖,票数不足\\n", window)
         mutex.Unlock()
         break
      
   

3. RWMutex读写锁

Go语言包中的sync包提供了两种锁类型:sync.Mutexsync.RWMutex。其中RWMutex是基于Mutex实现的,只读锁的实现使用类似引用计数器的功能。读写锁与互斥锁的最大不同是它可以针对读操作或写操作单独加锁,性能更高。

  • 多个协程可以同时读
  • 在一个协程写的时候,其他协程读写操作都不能进行
package main

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

var wg sync.WaitGroup
var rwMutex sync.RWMutex

func main() 
   wg.Add(3)
   go readData(1)
   go readData(2)
   go readData(3)
   wg.Wait()
   fmt.Println("读锁测试结束\\n")
   time.Sleep(3 * time.Second)

   wg.Add(3)
   go writeData(1)
   go readData(2)
   go writeData(3)
   wg.Wait()
   fmt.Println("写锁测试结束")


func readData(num int) 
   defer wg.Done()

   fmt.Println(num, "开始读")
   rwMutex.RLock()
   fmt.Println(num, "正在读...")
   time.Sleep(2 * time.Second)
   rwMutex.RUnlock()
   fmt.Println(num, "读结束,释放锁")


func writeData(num int) 
   defer wg.Done()

   fmt.Println(num, "开始写")
   rwMutex.Lock()
   fmt.Println(num, "正在写...")
   time.Sleep(2 * time.Second)
   rwMutex.Unlock()
   fmt.Println(num, "写结束,释放锁")

以上是关于golang/go语言sync同步包中的WaitGroup等待组Mutex互斥锁和RWMutex读写锁的主要内容,如果未能解决你的问题,请参考以下文章

golang/go语言sync同步包中的WaitGroup等待组Mutex互斥锁和RWMutex读写锁

浅谈errgroup的使用以及源码分析

golang [去阻塞频道]与Go#golang,#go,#go channels,#go synchronization,#goroutines,#waitgroups中的频道同步和阻止,

Go语言sync包中的WaitGroup使用实例

go包中的init() 函数

goruntine