EasyNVR拉转推视频流中采用互斥锁sync.Mutex和读写互斥锁sync.RWMutex的区别

在EasyNVR视频平台使用的视频直播项目场景中,经常会有多路推拉流的场景出现,因为基本是采用异步调用的方式,所以在多并发的情况下会出现数据不安全问题,这个时候就需要使用锁,来进行协程数据安全的处理。

Go语言包中的 sync 包提供了两种锁类型:sync.Mutex 和 sync.RWMutex。Mutex为互斥锁,适用于读写不确定场景,即读写次数没有明显的区别,并且只允许只有一个读或者写的场景;RWMutex是一个读写锁,该锁可以加多个读锁或者一个写锁,其经常用于读次数远远多于写次数的场景。

sync.Mutex 锁

该锁的结构体定义如下:

// A Mutex is a mutual exclusion lock.
// The zero value for a Mutex is an unlocked mutex.
//
// A Mutex must not be copied after first use.
type Mutex struct {
   state int32
   sema  uint32
}

该结构体主要实现了 Locker 接口,对外部暴露两个方法Lock() 和 Unlock()

// A Locker represents an object that can be locked and unlocked.
type Locker interface {
   Lock()
   Unlock()
}

该种锁的特点是,一旦 Lock() 锁定,其他所有协程都不能访问对应的数据,除非该协程调用 Unlock() 将锁释放出来。

在实际编码使用中,很少使用 sync.Mutex 锁,该种锁使用其他比较粗暴,为考虑读写的场景,在很多场景中,经常会有该种需求,一份数据在被读取的时候,其他协程也可以读取,但是一份数据在被写入新的数据时,不允许其他协程读写,因此又出现了 sync. RWMutex 这种读写锁的出现。读写锁,在实际使用中更高效。

sync. RWMutex锁

type RWMutex struct {
   w           Mutex  // held if there are pending writers
   writerSem   uint32 // semaphore for writers to wait for completing readers
   readerSem   uint32 // semaphore for readers to wait for completing writers
   readerCount int32  // number of pending readers
   readerWait  int32  // number of departing readers
}

读写锁也是依靠 sync.Mutex 这种锁来进行,该锁主要提供 RLock()、URLock()、Lock()和Unlock() 四个方法来。读锁为 RLock()方法,写锁为 Lock() 方法。其中对于读锁,不允许递归调用。以下是读锁的使用方式:

func (rw *RWMutex) RLock() {
   if race.Enabled {
      _ = rw.w.state
      race.Disable()
   }
   if atomic.AddInt32(&rw.readerCount, 1) < 0 {
      // A writer is pending, wait for it.
      runtime_SemacquireMutex(&rw.readerSem, false, 0)
   }
   if race.Enabled {
      race.Enable()
      race.Acquire(unsafe.Pointer(&rw.readerSem))
   }
}

sync 包中还提供了一些 sync.Map 和 sync.WaitGroup 等试用的结构体,在遇见对应的场景下再进行介绍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值