orDone
switch {
case <-channel[0]:
case <-channel[1]:
}
ゴルーチン
deferでclose
返り値 =
<-chan interface{}
Slide 6
Slide 6 text
orDone
switch {
case <-channel[0]:
case <-channel[1]:
}
ゴルーチン
deferでclose
返り値 =
<-chan interface{}
channel[0] or channel[1]の
ブロックが解除されたら
ゴルーチンが終了する。
その時のdeferでorDoneがcloseされる。
Slide 7
Slide 7 text
len(channels) == 3 の場合
Slide 8
Slide 8 text
orDone
switch {
case <-channel[0]:
case <-channel[1]:
case <-channel[2]:
case <-orDone:
}
ゴルーチン
deferでclose
返り値 =
<-chan interface{}
チャネルの数が変わっただけで、
len(channels) == 2 の時とほぼ同じ
Slide 9
Slide 9 text
orDone
switch {
case <-channel[0]:
case <-channel[1]:
case <-channel[2]:
case <-orDone:
}
ゴルーチン
deferでclose
返り値 =
<-chan interface{}
最後のcaseは再帰呼び出しの返り値。
case <-or(append(channels[3:], orDone)):
len(channels) == 3の場合、
orDoneが再帰呼び出しの返り値になる。
Slide 10
Slide 10 text
len(channels) == 4 の場合
Slide 11
Slide 11 text
orDone1
switch {
case <-channel[0]:
case <-channel[1]:
case <-channel[2]:
case <-orDone2:
}
ゴルーチン1
deferで
close
返り値 =
<-chan interface{}
switch {
case <-channel[3]:
case <-orDone1:
}
ゴルーチン2
orDone2
deferで
close
Slide 12
Slide 12 text
orDone1
switch {
case <-channel[0]:
case <-channel[1]:
case <-channel[2]:
case <-orDone2:
}
ゴルーチン1
deferで
close
返り値 =
<-chan interface{}
switch {
case <-channel[3]:
case <-orDone1:
}
ゴルーチン2
orDone2
deferで
close
↑再帰呼び出しでできたやつ
orDone2 := or(append(channels[3:], orDone1))
orDone1
switch {
case <-channel[0]:
case <-channel[1]:
case <-channel[2]:
case <-orDone2:
}
ゴルーチン1
deferで
close
返り値 =
<-chan interface{}
switch {
case <-channel[3]:
case <-orDone1:
}
ゴルーチン2
orDone2
deferで
close
パターン1 channel[3]がcloseされた場合
switchを抜け、
ゴルーチン2が終了する
Slide 17
Slide 17 text
orDone1
switch {
case <-channel[0]:
case <-channel[1]:
case <-channel[2]:
case <-orDone2:
}
ゴルーチン1
deferで
close
返り値 =
<-chan interface{}
switch {
case <-channel[3]:
case <-orDone1:
}
ゴルーチン2
orDone2
deferで
close
パターン1 channel[3]がcloseされた場合
switchΛൈ͚ͯ
ऴྃ
ゴルーチン終了時の
deferでorDone2をclose
Slide 18
Slide 18 text
orDone1
switch {
case <-channel[0]:
case <-channel[1]:
case <-channel[2]:
case <-orDone2:
}
ゴルーチン1
deferで
close
返り値 =
<-chan interface{}
switch {
case <-channel[3]:
case <-orDone1:
}
ゴルーチン2
orDone2
deferで
close
パターン1 channel[3]がcloseされた場合
switchΛൈ͚ͯ
ऴྃ
orDone2をcloseしたので、
switchを抜け、
ゴルーチン1が終了。
closed
Slide 19
Slide 19 text
orDone1
switch {
case <-channel[0]:
case <-channel[1]:
case <-channel[2]:
case <-orDone2:
}
ゴルーチン1
deferで
close
返り値 =
<-chan interface{}
switch {
case <-channel[3]:
case <-orDone1:
}
ゴルーチン2
orDone2
deferで
close
パターン1 channel[3]がcloseされた場合
switchΛൈ͚ͯ
ऴྃ
closed
switchΛൈ͚ͯ
ऴྃ
deferで
close
ゴルーチン終了時の
deferでorDone1をclose
Slide 20
Slide 20 text
orDone1
switch {
case <-channel[0]:
case <-channel[1]:
case <-channel[2]:
case <-orDone2:
}
ゴルーチン1
deferで
close
返り値 =
<-chan interface{}
switch {
case <-channel[3]:
case <-orDone1:
}
ゴルーチン2
orDone2
deferで
close
パターン1 channel[3]がcloseされた場合
switchΛൈ͚ͯ
ऴྃ
closed
switchΛൈ͚ͯ
ऴྃ
deferで
close
closed
✅ Done
Slide 21
Slide 21 text
パターン2
channel[0]~channel[2]のどれかがclose
Slide 22
Slide 22 text
orDone1
switch {
case <-channel[0]:
case <-channel[1]:
case <-channel[2]:
case <-orDone2:
}
ゴルーチン1
deferで
close
返り値 =
<-chan interface{}
switch {
case <-channel[3]:
case <-orDone1:
}
ゴルーチン2
orDone2
deferで
close
パターン2 channel[0] ~ channel[2] のどれかがcloseされた場合
switchを抜け、
ゴルーチン1が終了する
Slide 23
Slide 23 text
orDone1
switch {
case <-channel[0]:
case <-channel[1]:
case <-channel[2]:
case <-orDone2:
}
ゴルーチン1
deferで
close
返り値 =
<-chan interface{}
switch {
case <-channel[3]:
case <-orDone1:
}
ゴルーチン2
orDone2
deferで
close
switchΛൈ͚ͯ
ऴྃ
deferで
close
ゴルーチン終了時の
deferでorDone1をclose
パターン2 channel[0] ~ channel[2] のどれかがcloseされた場合
Slide 24
Slide 24 text
orDone1
switch {
case <-channel[0]:
case <-channel[1]:
case <-channel[2]:
case <-orDone2:
}
ゴルーチン1
deferで
close
返り値 =
<-chan interface{}
switch {
case <-channel[3]:
case <-orDone1:
}
ゴルーチン2
orDone2
deferで
close
switchΛൈ͚ͯ
ऴྃ
再帰呼び出し時に渡した
orDone1がcloseしたので、
switchを抜け、
ゴルーチン2も終了する
closed
パターン2 channel[0] ~ channel[2] のどれかがcloseされた場合
※再帰呼び出し時に呼び出し側のorDone(例のorDone1)を渡すのは、
子ゴルーチン(例のゴルーチン2)をcloseするため
Slide 25
Slide 25 text
orDone1
switch {
case <-channel[0]:
case <-channel[1]:
case <-channel[2]:
case <-orDone2:
}
ゴルーチン1
返り値 =
<-chan interface{}
switch {
case <-channel[3]:
case <-orDone1:
}
ゴルーチン2
orDone2
deferで
close
switchΛൈ͚ͯ
ऴྃ
switchΛൈ͚ͯ
ऴྃ
closed
deferで
close
✅ Done
パターン2 channel[0] ~ channel[2] のどれかがcloseされた場合