首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过锁请求时间获得同步锁

通过锁请求时间获得同步锁
EN

Stack Overflow用户
提问于 2018-12-12 12:33:29
回答 1查看 74关注 0票数 0

我有一个程序,我们称之为mainRoutine,它锁定了一个资源,而另一边,我们将命名为goroutine-0 goroutine-1 goroutine-2 .这个例程试图获得锁,在mainRoutine停止后,我需要我的另一个goroutine以同步的方式获得锁,我的意思是我想要goroutine-0然后goroutine-1 .为了解决这个问题,我所做的就是将time.Time的一部分填充到time.Now()中,在其中启动了goroutine,并使用了sync.Cond。一些代码示例来说明:

代码语言:javascript
复制
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,它总是称为切片的第一个elem。

代码语言:javascript
复制
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")
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-12 14:03:06

给大猩猩一个内部标识,然后让他们按顺序相互呼叫。下面是一个例子,说明它是如何工作的

代码语言:javascript
复制
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")
}

3

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53743126

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档