💬
Goによる並列処理のお勉強(Buffering)
そろそろ、ソフトウエア工学に出戻りしないとと、最近Goをいろい始めました。まずは、以下のプログラムをみて、なぜ、デッドロックするか分かりますか?
package main
import (
"fmt"
"time"
)
func main() {
const N = 3
const capacity = N
req := make(chan int, capacity) // リクエスト用(バッファ付き)
start := make(chan struct{}) // サーバ開始合図(非バッファ)
done := make(chan struct{}) // 終了通知
// サーバ
go func() {
fmt.Println("[server] waiting start signal...")
<-start // 合図が来るまで絶対に読み出しを始めない
fmt.Println("[server] started")
for i := 0; i < N; i++ {
v := <-req // ここは普通に受信
fmt.Println("[server] got request:", v)
time.Sleep(50 * time.Millisecond)
}
close(done)
}()
// クライアント
go func() {
fmt.Println("[client] sending", N, "requests...")
for i := 0; i <= N; i++ {
fmt.Println("[client] send:", i)
req <- i
}
fmt.Println("[client] all requests enqueued, sending start signal")
start <- struct{}{}
}()
select {
case <-done:
fmt.Println("[main] finished successfully")
case <-time.After(2 * time.Second):
fmt.Println("[main] timed out (likely deadlock)")
}
}
あなたのプログラムは見えないバッファのおかげで辛うじて、動いているとかないですよね???
Discussion