Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Go言語による並行処理「4.4 orチャネル」の図
Search
Hiroyuki ANAI
October 05, 2021
Technology
510
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Go言語による並行処理「4.4 orチャネル」の図
コードを読んでいて混乱したので図にしました。
Hiroyuki ANAI
October 05, 2021
More Decks by Hiroyuki ANAI
See All by Hiroyuki ANAI
安心して変更できるWebフロントエンドの作り方
pirosikick
7
3.3k
書き換えて学ぶTemporal #fukts
pirosikick
2
510
fukuoka.ts #3 社内でESLintの共通設定を配りたい2025年春版
pirosikick
3
510
compilerOptions、全部読んだ
pirosikick
1
310
Step Functionsの設計時に知っておいたほうがいいかもしれないこと
pirosikick
0
560
サイボウズWebフロントエンド脱レガシーの今までとこれから
pirosikick
6
17k
@cybozu/eslint-configから学ぶ、全社共通ESLint configの運用
pirosikick
4
1.9k
Web Share Target API #w3fukuoka
pirosikick
0
750
Google I/O '19のWebをまとめる会
pirosikick
2
900
Other Decks in Technology
See All in Technology
形式手法を使って仕様をコーディングしよう
mikanichinose
0
180
メルペイ 会計システム概要と歴史
mewuto
0
150
事業活動を AI Ready にする攻めと守りのデータエンジニアリング / data-engineering-for-ai-ready-business
pei0804
1
100
OpenSharing について熱く語る〜AI アセットの共有について〜
kameitomohiro
0
230
Execution in the Kingdom of Agents: Reflections on Abstraction and Complexity
bcantrill
0
840
使いこなすために知っておきたい Azure SRE Agent アンチパターン
torumakabe
2
330
Swap and Memory Reclaim - Squeezing Out More RAM
ennael
PRO
1
1.6k
雪かき部 #7 もう怖くない!SELECT文!
foursue
0
280
React Nativeでの OTA Updateって、 どう説明する?
ichiki1023
0
140
大阪オフィスに Unitree Go2 がやってきたので Physical AI やってみた
dafujii
0
300
freeeらしさをAIとともに作る / Creating the freee Experience with AI
ymrl
0
190
AIは爆速なのに、私が詰まっていた話 ― 音声入力と鳴くマスコットでボトルネックを削る
yama3133
0
520
Featured
See All Featured
Google's AI Overviews - The New Search
badams
0
1.6k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
540
Exploring anti-patterns in Rails
aemeredith
4
520
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
A Tale of Four Properties
chriscoyier
163
24k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
490
Code Reviewing Like a Champion
maltzj
528
40k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
46k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
720
Discover your Explorer Soul
emna__ayadi
2
1.3k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.5k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Transcript
GoݴޠʹΑΔ ฒߦॲཧ 4.4 orνϟωϧͷਤ @pirosikick
• var or(channels ...<-chan interface{}) <-chan interface{} • "1つ以上のdoneチャネルを1つのdoneチャネルにまとめて、
まとめているチャネルのうちのどれか1つのチャネルが閉じられたら、 まとめたちゃねるも閉じられるようにしたい" • <-or( done1, done2, done3, ) • 再帰処理で実装されており、 コードを読んでいると混乱してしまったので、図にしてみました。
len(channels) == 0 の場合 返り値は nil 返り値は channels[0] len(channels) ==
1 の場合
len(channels) == 2 の場合
orDone switch { case <-channel[0]: case <-channel[1]: } ゴルーチン deferでclose
返り値 = <-chan interface{}
orDone switch { case <-channel[0]: case <-channel[1]: } ゴルーチン deferでclose
返り値 = <-chan interface{} channel[0] or channel[1]の ブロックが解除されたら ゴルーチンが終了する。 その時のdeferでorDoneがcloseされる。
len(channels) == 3 の場合
orDone switch { case <-channel[0]: case <-channel[1]: case <-channel[2]: case
<-orDone: } ゴルーチン deferでclose 返り値 = <-chan interface{} チャネルの数が変わっただけで、 len(channels) == 2 の時とほぼ同じ
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が再帰呼び出しの返り値になる。
len(channels) == 4 の場合
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
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 { … } ゴルーチン1 deferで close 返り値 =
<-chan interface{} switch { … } ゴルーチン2 orDone2 deferで close <-chan interface{} switch { … } ゴルーチン3 orDone3 deferで close <-chan interface{} ・ ・ ・ channelが3つにつき、 1ゴルーチンずつ増えていく
len(channels) == 4 の場合 で動作をみる
パターン1 channel[3]がclose
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が終了する
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
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
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
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
パターン2 channel[0]~channel[2]のどれかがclose
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が終了する
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された場合
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するため
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された場合
͓ΘΓ