通过锁请求时间同步获取锁
来源:stackoverflow
时间:2024-04-09 22:00:37 190浏览 收藏
来到golang学习网的大家,相信都是编程学习爱好者,希望在这里学习Golang相关编程知识。下面本篇文章就来带大家聊聊《通过锁请求时间同步获取锁》,介绍一下,希望对大家的知识积累有所帮助,助力实战开发!
问题内容
我有一个带有 goroutine 的程序,我们将其称为 mainroutine,它锁定资源,在另一边,我们将调用其他 goroutine,将其命名为 goroutine-0 goroutine-1 goroutine-2 .... 该例程尝试获取锁,在 mainroutine 停止后,我需要我的另一个 goroutine 以同步方式获取锁,我的意思是我想要 goroutine-0 然后 goroutine-1 ... 为了解决这个问题,我所做的是用 time.now() 填充 goroutine 启动时的 time.time 切片,并使用sync.cond。 一些代码示例来说明:
package main import ( "fmt" "sync" "time" ) func condition(mytime time.time, timeslice []time.time) bool { for _, v := range timeslice { if mytime.after(v) { return false } } return true } func removefromslice(mytime time.time, timeslice []time.time) { var place int for i, v := range timeslice { if mytime.equal(v) { place = i break } } timeslice = append(timeslice[:place], timeslice[place+1:]...) } func main() { var m sync.mutex c := sync.newcond(&m) c.l.lock() fmt.println("locker locked") go func() { time.sleep(time.second * 1) c.l.unlock() fmt.println("locker unlocked") }() var wg sync.waitgroup var timeslice []time.time wg.add(100) for i := 0; i < 100; i++ { now := time.now() timeslice = append(timeslice, now) time.sleep(time.nanosecond * 1) // ensure there's at leat 1 nanosec of diff between 2 time.now go func(i int, mytime time.time) { fmt.printf("before %d %d\n", i, mytime.unix()) c.l.lock() for !condition(mytime, timeslice) { c.wait() } c.l.unlock() removefromslice(mytime, timeslice) c.broadcast() wg.done() fmt.printf("after done %d\n", i) }(i, now) } wg.wait() fmt.println("hello, playground") }
我认为这不是做这种事情的正确方法,它看起来真的很hacky,有更好的方法吗?
-- 编辑-- 在 @vorsprung 的回答之后,我认为在我的情况下最好的方法是制作一个 func 切片,它总是调用切片的第一个元素
package main import ( "fmt" "sync" ) func makeFunc(id int) func() { return func() { fmt.Printf("called %d\n", id) } } func main() { var wg sync.WaitGroup var funcSlice []func() var m sync.Mutex for i := 0; i < 5; i++ { funcSlice = append(funcSlice, makeFunc(i)) wg.Add(1) go func() { defer wg.Done() m.Lock() defer m.Unlock() funcSlice[0]() funcSlice = funcSlice[1:] }() } wg.Wait() fmt.Println("finished") }
解决方案
给 goroutine 一个内部 id,然后让它们按顺序互相调用。下面是其工作原理的示例
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup var c [5]chan int for i := range c { c[i] = make(chan int) wg.Add(1) go func(id int) { defer wg.Done() f := <-c[id] fmt.Println("called from ", f, ". My id ", id) if id < 4 { fmt.Println(id+1, " next") c[id+1] <- id } fmt.Println("ending ", id) }(i) } c[0] <- 99 wg.Wait() fmt.Println("bye") }
https://play.golang.org/p/psF8ISodJU_3
以上就是《通过锁请求时间同步获取锁》的详细内容,更多关于的资料请关注golang学习网公众号!
声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
-
502 收藏
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
最新阅读
更多>
-
139 收藏
-
204 收藏
-
325 收藏
-
477 收藏
-
486 收藏
-
439 收藏
-
357 收藏
-
352 收藏
-
101 收藏
-
440 收藏
-
212 收藏
-
143 收藏
课程推荐
更多>
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习