猿问

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

我有一个带有 goroutine 的程序,我们将调用 mainRoutine 来锁定资源,在另一侧的其他 goroutines of fired 我们将命名为 goroutine-0 goroutine-1 goroutine-2 .... 这个例程尝试获取锁,在 mainRoutine 停止后我需要我的另一个 goroutine 以同步方式获取锁,我的意思是我想要 goroutine-0 然后 goroutine-1 ...我为面对这个问题所做的是一段时间.Time 填充了 goroutine 启动时的 time.Now(),并使用了 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")

}

我不认为这是做这种事情的正确方法,它看起来真的很老套,有没有更好的方法?


-- 编辑 -- 在@Vorsprung 的回答之后,我认为在我的案例中最好的方法是制作一个 func 切片,它总是调用切片的第一个元素


package main


import (

    "fmt"

    "sync"

)


func makeFunc(id int) func() {

    return func() {

        fmt.Printf("called %d\n", id)

    }

}


撒科打诨
浏览 110回答 1
1回答

月关宝盒

给 goroutines 一个内部 id,然后让它们按顺序相互调用。这可能如何工作的示例如下package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "sync")func main() {&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; var c [5]chan int&nbsp; &nbsp; for i := range c {&nbsp; &nbsp; &nbsp; &nbsp; c[i] = make(chan int)&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go func(id int) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f := <-c[id]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("called from ", f, ".&nbsp; My id ", id)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if id < 4 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(id+1, " next")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c[id+1] <- id&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("ending ", id)&nbsp; &nbsp; &nbsp; &nbsp; }(i)&nbsp; &nbsp; }&nbsp; &nbsp; c[0] <- 99&nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; fmt.Println("bye")}https://play.golang.org/p/psF8ISodJU_3
随时随地看视频慕课网APP

相关分类

Go
我要回答