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
320
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
自分で立ててみるLLMサービス
y_sera15
0
160
FactoryBotアンチパターン / factory_bot anti-patterns
toshimaru
0
140
初対面のメンバーがチームを組み、Claude Codeでゼロからサービスをリリース
mkdev10
1
120
Loop Engineering これくらいでいい
mikanichinose
0
200
OSC2026on_the-world-is-waiting-for-your-voice.pdf
naruoga
0
370
LocalStack を使ったサーバーレスアプリケーション開発 / Serverless Development with LocalStack
kakakakakku
1
370
生成AIを使って「人が」考える技術 ― AI時代の人機共想と実践ノウハウ|UNITT AC2026
ishiirikie
0
580
カンファレンスに参加した後の浮遊感とセルフケア
pauli
0
320
DWH の限界突破! AI エージェント向け爆速リアルタイムデータ基盤 ClickHouse
jozono
1
360
生成AIで高い生産性を求められて、 悩み、乗り越えた話
mot_techtalk
2
150
子育てエンジニアの可処分時間が減っても成長を諦めない戦い方
sudoakiy
6
4.4k
組み立てて楽しむ AWS Blocks 入門
kmiya84377
0
230
Featured
See All Featured
How to train your dragon (web standard)
notwaldorf
96
6.9k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
68
58k
Rails Girls Zürich Keynote
gr2m
96
14k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
390
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
69
67k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
740
My Coaching Mixtape
mlcsv
0
350
Context Engineering - Making Every Token Count
addyosmani
9
1.2k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
A Soul's Torment
seathinner
8
3.7k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
720
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
620
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された場合
͓ΘΓ