当前位置:网站首页>利用go通道channel实现互斥锁
利用go通道channel实现互斥锁
2022-07-29 21:43:00 【kankan231】
利用通道的阻塞特性,可以创建一个缓冲大小为1的通道,只有第一个往通道里放数据的协程会成功,其它的只能阻塞等待,这个过程相当于加锁,获得锁的协程任务执行完毕后往通道中取出数据就是解锁,然后其他的协程就可以继续获得锁了,实现代码如下:
package main
import (
"fmt"
"time"
)
type Lock struct {
ch chan struct{}
}
func NewLock() *Lock {
l:=&Lock{}
l.ch = make(chan struct{},1)
return l
}
//获取锁,未获取到一直阻塞
func (l *Lock) Lock() {
l.ch <- struct{}{}
}
//尝试获取锁,无论是否获取到锁,立即返回
func (l *Lock) TryLock() bool {
select {
case l.ch <- struct{}{}:
return true
default:
return false
}
}
//尝试获取锁,在规定时间内仍未获得锁则返回
func (l *Lock) TryLockWithTimeout(t time.Duration) bool {
timer:=time.NewTimer(t)
select {
case l.ch <- struct{}{}:
timer.Stop()
return true
case <-timer.C:
return false
}
}
//解锁
func (l *Lock) Unlock() {
select {
case <- l.ch:
return
default:
}
}
var l *Lock
func main() {
l = NewLock()
go task(1)
go task(2)
go task(3)
time.Sleep(8*time.Second)
}
func task(i int) {
l.Lock()
defer l.Unlock()
fmt.Println("任务",i,"开始执行")
time.Sleep(2*time.Second)
fmt.Println("任务",i,"执行完毕")
}
执行结果:
任务 1 开始执行
任务 1 执行完毕
任务 2 开始执行
任务 2 执行完毕
任务 3 开始执行
任务 3 执行完毕边栏推荐
猜你喜欢
随机推荐
研究生怎么申请专利,流程是什么?
聊聊阻容降压原理 和 实际使用的电路
[BUG]一个数组new的时候sizeof()忘乘上个数
华东师范大学副校长周傲英:数据赋能,从数据库到数据中台
在Ferora35中安装oracle-database-xe-21c
Add a logo to the upper left corner of the picture, add time and address to the lower left corner, and wrap the line when the address reaches the specified length
ict的终极模式 是软件研发
php反序列化结构知识点实例分析
GBASE 8s 数据库的大对象和日志备份
高等数学(第七版)同济大学 习题3-7 个人解答
获取七牛云地址文件保存到本地
阿里 P8 爆出的这份大厂面试指南,看完工资暴涨 30k!
Sorry, it's hard for you to earn middle-aged money
03-树3 Tree Traversals Again(树的遍历)
转:idea中language level设置
新库上线 | CnOpenData国际货运代理信息数据
Verilog 加法器设计
【点云】M3DeTR: Multi-representation, Multi-scale, Mutual-relation 3D Object Detection with Transformers
Leetcode 705.设计哈希集合
GBASE 8s 数据库的备份创建







![[BUG]一个数组new的时候sizeof()忘乘上个数](/img/d7/fa821aee0626e715bbb4e422e7e2fb.png)

