• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

go条件变量的使用和原理

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

场景

最近写代码时碰到一个场景, 需要使用 map[int]struct{} 结构来存储task, map的key是task的id,随时可以增减。因为的确除了看书,基本上没使用过条件变量所以后面过了一天才想到可以用条件变量来实现。记得在某篇博客上看到的一句话挺不错,大概是同步语句中,条件变量的特点在于等待。

一开始代码大概是这样的

事件循环

func Loop() {
	for {
    	mutex.Lock()
		for taskId, task := range tasks {
    		// handle code
		}
    	lenght := len(task)
    	mutex.UnLock()

		// 为了减少cpu空转  当队列为空的时候sleep 2秒
        if length == 2 {
    		time.Sleep(time.Secord * 2)
        }
    }
}   

新增task(删除也是类似)

func addTask(t *Task) {
    mutex.Lock()
    tasks[t.Id] = t
    mutex.UnLock()
}

使用条件变量

使用条件变量之后的事件循环代码

func Loop() {
    for {
        mutex.Lock()
        // 如果当前任务数为0 调用Wait()等待新任务增加时唤醒
        if len(tasks) == 0 {
            cond.Wait() // cond := sync.NewCond(&mutex)
        }

		for taskId, task := range tasks {
    		// handle code
		}
        mutex.UnLock()
    }
}

新增task(删除task代码不作改变)

func addTask(t *Task) {
    mutex.Lock()
    tasks[t.Id] = t
    if len(task) == 1 {  // 从0->1 可能之前有goruntine阻塞
    	cond.Signal()    // 由于Loop()是单协程在跑所以 使用的是Signal()足矣
    }
    mutex.UnLock()
}

条件变量原理(和语言无关)

如果是C语言的pthread_cond条件变量和GO最主要的区别,本质上还是协程和真正的内核线程的区别, go 自带sync包里的条件变量 对goruntine的操作,其阻塞/唤醒不需要陷入内核态。

Wait()

func (c *Cond) Wait() {
    c.checker.check()
    t := runtime_notifyListAdd(&c.notify)  // 等待的goruntine数+1
    c.L.Unlock() // 释放锁资源
    runtime_notifyListWait(&c.notify, t) // 阻塞,等待其他goruntine唤醒
    c.L.Lock() // 获取资源
}

Signa() 和 BroadCast()

func (c *Cond) Signal() {
    c.checker.check()
    runtime_notifyListNotifyOne(&c.notify) // 唤醒最早被阻塞的goruntine
}

func (c *Cond) Broadcast() {
    c.checker.check()
    runtime_notifyListNotifyAll(&c.notify) // 唤醒所有goruntine
}

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
go处理form表单输入发布时间:2022-07-10
下一篇:
Go语言操作Redis发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap