チャネルを使用してキューを実装する演習に取り組んでいます。具体的には、チャネルのサイズを使用して同時ゴルーチンの数を制限しようとしています。つまり、次のコードを書きました。
package main
import "fmt"
import "time"
import "math/rand"
func runTask (t string, ch *chan bool) {
start := time.Now()
fmt.Println("starting task", t)
time.Sleep(time.Millisecond * time.Duration(rand.Int31n(1500))) // fake processing time
fmt.Println("done running task", t, "in", time.Since(start))
<- *ch
}
func main() {
numWorkers := 3
files := []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"}
activeWorkers := make(chan bool, numWorkers)
for _, f := range files {
activeWorkers <- true
fmt.Printf("activeWorkers is %d long.\n", len(activeWorkers))
go runTask(f, &activeWorkers)
}
select{}
}
現在、コードは次のようにクラッシュします。
throw: all goroutines are asleep - deadlock!
私の期待は、select の呼び出しが永久にブロックされ、ゴルーチンがデッドロックなしで終了することでした。
したがって、2 つの質問があります。select が永久にブロックされないのはなぜですか。また、for ループの後に time.Sleep() 呼び出しをスローする以外に、どうすればデッドロックを回避できますか?
乾杯、
-mtw