为了账号安全,请及时绑定邮箱和手机立即绑定

通过锁请求时间同步获取锁

通过锁请求时间同步获取锁

Go
撒科打诨 2023-05-15 15:19:11
我有一个带有 goroutine 的程序,我们将调用 mainRoutine 来锁定资源,在另一侧的其他 goroutines of fired 我们将命名为 goroutine-0 goroutine-1 goroutine-2 .... 这个例程尝试获取锁,在 mainRoutine 停止后我需要我的另一个 goroutine 以同步方式获取锁,我的意思是我想要 goroutine-0 然后 goroutine-1 ...我为面对这个问题所做的是一段时间.Time 填充了 goroutine 启动时的 time.Now(),并使用了 sync.Cond。一些代码示例来说明:package mainimport (    "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")}我不认为这是做这种事情的正确方法,它看起来真的很老套,有没有更好的方法?-- 编辑 -- 在@Vorsprung 的回答之后,我认为在我的案例中最好的方法是制作一个 func 切片,它总是调用切片的第一个元素package mainimport (    "fmt"    "sync")func makeFunc(id int) func() {    return func() {        fmt.Printf("called %d\n", id)    }}
查看完整描述

1 回答

?
月关宝盒

TA贡献1772条经验 获得超5个赞

给 goroutines 一个内部 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


查看完整回答
反对 回复 2023-05-15
  • 1 回答
  • 0 关注
  • 109 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信