該当のソースコード
発生している問題・エラーメッセージ
期待する結果は以下の通りなのですが、
{"success":true,"id":1} {"success":true,"id":2} {"success":true,"id":3} {"success":false,"id":4} {"success":true,"id":5} {"success":false,"id":6} {"id":7,"feed":[{"body":"Another post to add","timestamp":43242421}]}
以下のコマンドで2つのサブスレッドを発生させると(一つ目のコマンド引数がスレッドの数です。)、デッドロックを起こしてしまいます。
$ twitter kazukiegusa$ go run twitter.go 2 4 < tasks.json {"success":true,"id":1} {"success":true,"id":2} {"success":true,"id":3} {"success":false,"id":4} {"success":false,"id":6} {"id":7,"feed":[{"body":"Another post to add","timestamp":43242421}]} fatal error: all goroutines are asleep - deadlock! goroutine 1 [semacquire]: sync.runtime_Semacquire(0xc000016088) /usr/local/go/src/runtime/sema.go:56 +0x42 sync.(*WaitGroup).Wait(0xc000016080) /usr/local/go/src/sync/waitgroup.go:130 +0x64 main.main() /Users/kazukiegusa/mpcs/Parallel Programming/egusa/proj1/twitter/twitter.go:66 +0x422 exit status 2
実現したいこと&わからないこと
質問の箇所は、twitter.go
内にあります。まず、main
関数の中で、コンディション変数を定義しています。
Go
1・・・中略・・・ 2 3var wg sync.WaitGroup 4 5cond := sync.NewCond(new(sync.Mutex)) // Conditional variable 6 7for i := 0; i < numGoroutines; i++ { 8 wg.Add(1) 9 go consumer(q, f, blockSize, cond, &wg) 10} 11 12producer(q, cond) 13 14// 全てのサブスレッドがconsumer関数の実行を終えるまで待つ 15wg.Wait()
producer
関数の中では、エンキュー(Enqueue)するごとに、sync.Cond
のSignal
関数を使って、consumer
関数内で待機しているスレッドを一つ呼び起こしています。
func producer(q *queue.Queue, cond *sync.Cond) { ・・・中略・・・ for { ・・・中略(ここにエンキュー(Enqueue)を実行するコードが入ります。)・・・ // 待機中のサブスレッドを一つ呼び起こす cond.Signal() } }
consumer
関数内では、初期化するときにsync.Cond
に紐付けたMutexを使ってロックしています。
func consumer(q *queue.Queue, f feed.Feed, blockSize int64, cond *sync.Cond, wg *sync.WaitGroup) { cond.L.Lock() // キューが空なら待機する cond.Wait() ・・・中略(ここにデキュー(Dequeue)を実行するコードが入ります。)・・・ cond.L.Unlock() wg.Done() }
試したこと
いろいろ試しましたが、sync.Condの挙動がきちんと把握できていないのかなと思っています。
よろしくお願い致します。
タイトル通りの質問内容にまとめて欲しい・・・。
sync.Condにどのような挙動を期待していて試してみたことに絞って質問してもらえれば回答がつきやすいと思います。
ご指摘ありがとうございます!質問を修正してみました。
コードも多少変えています。どうやらデッドロックが起きてしまっているみたいです。
回答1件
あなたの回答
tips
プレビュー