我有一个带有 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
- 1 回答
- 0 关注
- 109 浏览
添加回答
举报
0/150
提交
取消