Go
1package main 2 3import ( 4 "fmt" 5 "math/rand" 6 "time" 7) 8 9const goroutines = 10 10const maxProcesses = 3 11 12func main() { 13 //3つまでint型を受け取れるチャネル 14 semaphore := make(chan int, maxProcesses) 15 //10つまでint型を受け取れるチャネル 16 notify := make(chan int, goroutines) 17 18 for i := 0; i < goroutines; i++ { 19 fmt.Println(i, "i") 20 go func(no int, semaphore chan int, notify chan<- int) { 21 //semaphoreに0を送信 22 semaphore <- 0 23 //ランダムな秒数で処理を一時停止させる 24 time.Sleep(time.Duration(rand.Int63n(3)) * time.Second) 25 //semaphoreに送信された値を取り出してバッファを解放する。解放しなかれば3回ループした時点で止まる。 26 fmt.Println(<-semaphore, "semaphore受信") 27 //notifyに引数のnoを送信する 28 notify <- no 29 }(i, semaphore, notify) 30 } 31 for i := 0; i < goroutines; i++ { 32 //notifyに送信された値を全て取り出す。同期の意味合いも持つ 33 fmt.Println(<-notify, "notify受信") 34 } 35 fmt.Println("全て完了") 36}
基礎からわかるGo言語という書籍のサンプルコードを少し変形させて、自分なりの理解をコメントにしました。
もし理解に誤りがあるようなら指摘してくださると嬉しいです。
本題に入りまして、今つまづいているのはsemaphoreの部分です。
このコードを実行させると大体の場合、forのiの0から3以上が表示されて、
その後、semaphoreの受信が表示されるのですが、その前にsemaphore <- 0の部分が3つまでしか受け取れないのでエラーが起きてしまうように感じます。
<- semaphoreでバッファの解放?を行っているみたいですが、先にiが3以上まで表示されるという事は、解放する前に受け取っているという事なので、エラーが起きないのが何故なのか理解出来てない状況です...
わかるかたいらしたらお願いします
fmt.Println(<-semaphore, "semaphore受信")
の部分をコメントアウトした時のエラーメッセージ
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
C:/Go/src/mytest/test1.go:33 +0x18b
goroutine 5 [chan send]:
main.main.func1(0x0, 0xc04206a080, 0xc042076000)
C:/Go/src/mytest/test1.go:22 +0x3e
created by main.main
C:/Go/src/mytest/test1.go:20 +0x14b
goroutine 6 [chan send]:
main.main.func1(0x1, 0xc04206a080, 0xc042076000)
C:/Go/src/mytest/test1.go:22 +0x3e
created by main.main
C:/Go/src/mytest/test1.go:20 +0x14b
goroutine 7 [chan send]:
main.main.func1(0x2, 0xc04206a080, 0xc042076000)
C:/Go/src/mytest/test1.go:22 +0x3e
created by main.main
C:/Go/src/mytest/test1.go:20 +0x14b
goroutine 10 [chan send]:
main.main.func1(0x5, 0xc04206a080, 0xc042076000)
C:/Go/src/mytest/test1.go:22 +0x3e
created by main.main
C:/Go/src/mytest/test1.go:20 +0x14b
goroutine 11 [chan send]:
main.main.func1(0x6, 0xc04206a080, 0xc042076000)
C:/Go/src/mytest/test1.go:22 +0x3e
created by main.main
C:/Go/src/mytest/test1.go:20 +0x14b
goroutine 12 [chan send]:
main.main.func1(0x7, 0xc04206a080, 0xc042076000)
C:/Go/src/mytest/test1.go:22 +0x3e
created by main.main
C:/Go/src/mytest/test1.go:20 +0x14b
goroutine 13 [chan send]:
main.main.func1(0x8, 0xc04206a080, 0xc042076000)
C:/Go/src/mytest/test1.go:22 +0x3e
created by main.main
C:/Go/src/mytest/test1.go:20 +0x14b
exit status 2
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/07/17 04:33 編集
2018/07/17 07:16
2018/07/17 08:18
2018/07/17 08:38
2018/07/17 09:41
2018/07/17 11:06
2018/07/17 11:17
2018/07/17 11:34 編集