我有一個帶有 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 關注
- 133 瀏覽
添加回答
舉報
0/150
提交
取消