fugaの内容をMutexで再入不可能にするとfugaの処理がシーケンシャルになるので
ご希望のように出力が入り混じることはなくなります。
ただし、fugaが並列に実行されることはなくなりますのでgoroutineに載せることによる効率化はありません。
https://play.golang.org/p/tEHVL76Dm6Q
go
1package main
2
3import (
4 "fmt"
5 "sync"
6)
7
8func main() {
9 ch := make(chan bool, 10)
10 for i := 0; i < 100; i++ {
11 ch <- true
12 go func() {
13 fuga()
14 <-ch
15 }()
16 }
17}
18
19var mu sync.Mutex
20
21func fuga() {
22 mu.Lock()
23 defer mu.Unlock()
24 hoge1()
25 hoge2()
26}
27
28func hoge1() {
29 common()
30 fmt.Println("hoge1")
31}
32
33func hoge2() {
34 common()
35 fmt.Println("hoge2")
36}
37
38func common() {
39 fmt.Println("common")
40}
大切なのは出力がcommonが決めた内容とhoge#が決めた内容が「一塊」であるということ。
実装例のひとつは以下の通り。
messageQueueには文字列スライスを投入可能にして、
- common決定した文字列とhoge1が決定した文字列をセットでキューに投げ込む
- common決定した文字列とhoge2が決定した文字列をセットでキューに投げ込む
別のgoroutineでmessageQueueの内容をひたすらfmt.Printする。
https://play.golang.org/p/DyFpZfb1YLb
go
1package main
2
3import (
4 "fmt"
5)
6
7func main() {
8 messageQueue := make(chan []string, 10)
9 go func() {
10 for v := range messageQueue {
11 for _, s := range v {
12 fmt.Println(s)
13 }
14 }
15 }()
16 ch := make(chan bool, 10)
17 for i := 0; i < 100; i++ {
18 ch <- true
19 go func() {
20 fuga(messageQueue)
21 <-ch
22 }()
23 }
24}
25
26func fuga(msg chan<- []string) {
27 hoge1(msg)
28 hoge2(msg)
29}
30
31func hoge1(msg chan<- []string) {
32 msg <- []string{common(), "hoge1"}
33}
34
35func hoge2(msg chan<- []string) {
36 msg <- []string{common(), "hoge2"}
37}
38
39func common() string {
40 return "common"
41}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/25 10:15