GO语言-锁操作

概述

sync包文档:Package sync - The Go Programming Language

sync包提供了基本同步的操作,如互斥锁等。除了Once和 WaitGroup之外,大多数类型都是提供低级库例程使用的。而更高级的的同步最好是通过channel和通信来完成。

互斥锁 Mutex

互斥锁比较暴力,当一个goroutine获得了互斥锁之后,其他的goroutine只能等待释放锁。

使用互斥锁时,对资源操作完一定要解锁,否则程序会死锁。建议使用defer语句来解锁。

//定义互斥锁对象
var mutex_name sync.Mutex

//上锁
mutex_name.Lock()
//解锁
mutex_name.Unlock()

同样是的火车站售票问题,我们看一下通过互斥锁解决临界资源问题的效果

//车票余量
var tickets = 5

//定义同步等待组
var wg sync.WaitGroup

//定义互斥锁对象
var mutex sync.Mutex

func main() {
	wg.Add(3)
	go saleTickets("1号售票口")
	go saleTickets("2号售票口")
	go saleTickets("3号售票口")
	wg.Wait()
}

func saleTickets(name string) {
	for {
		mutex.Lock()
		if tickets > 0 {
			fmt.Printf("车票剩余:%v, %v售出\n", tickets, name)
			tickets--
			time.Sleep(1 * time.Second)
		} else {
			mutex.Unlock()
			fmt.Println("车票已售罄...")
			wg.Done()
			break
		}
		mutex.Unlock()
	}
}

 

读写锁 RWMutex

读写锁和普通的互斥锁不同的是,它是一种专门针对读操作和写操作的互斥锁。

读写锁同一时刻允许有多个读操作在进行,但在同一时刻只允许有一个写操作在进行。并且在某一个写操作进行过程中,读操作也是不可以进行的。所以说,读写锁对于读操作可以同时并发,但是对于写操作是完全互斥的。

//定义读写锁锁对象
var rwmutex_name sync.RWMutex

//读锁
rwmutex_name.RLock
//读解锁
rwmutex_name.RUnlock

//写锁
rwmutex_name.Lock
//写解锁
rwmutex_name.Unlock

读写锁我们就不进行示例的展示了,因为和上面互斥锁展示的示例效果应该差别不大。

        对写锁实际解决的问题是,使用互斥锁带来并发能力降低的问题。因为互斥锁不论读操作还是写操作都会阻塞,程序从并发变成了串行。

        而实际上对于不会对临界资源产生修改的读操作,我们是不需要阻塞的;只有对临界资源需要修改的写操作,我们才需要阻塞。所以读写锁就是为了提高程序加锁时的并发能力。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值