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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Hiroyuki ANAI
October 05, 2021
Technology
500
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
5
2.7k
書き換えて学ぶTemporal #fukts
pirosikick
2
450
fukuoka.ts #3 社内でESLintの共通設定を配りたい2025年春版
pirosikick
3
500
compilerOptions、全部読んだ
pirosikick
1
310
Step Functionsの設計時に知っておいたほうがいいかもしれないこと
pirosikick
0
550
サイボウズ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
Vibe Coding で作ったプロダクトをどう安全に動かすか / How to Safely Run Products Built with Vibe Coding
glidenote
0
170
技術的負債から考える、AI時代のエンジニアリング投資 — ビズリーチの技術的負債と向き合った経験から、変更し続けられるソフトウェアを考える/ technical-debt-con2026
visional_engineering_and_design
4
3.2k
CLIライブラリ開発を支える技術
htnabe
0
130
アプリログインとWeb認証基盤をつなぐ ASWebAuthenticationSession 作法
shimastripe
1
340
おい、エージェントを使って終わらせろ
nwiizo
1
690
研究開発部の紹介 / Sansan R&D Profile
sansan33
PRO
5
25k
AIを活用するために決めた "やらないこと" - 価値に注目する / Not betting on AI
soudai
PRO
3
550
SREの視点で考えるSIEM活用術 〜AWS環境でのセキュリティ強化〜
cscengineer
PRO
0
110
AIエージェントの一手は 誰も見ていない - Falco拡張OSS「Prempti」とeBPFで サーバーレス実行基盤を二層防御する
keitah
0
220
エージェントはローカル、検証はMicroVM — Lambda MicroVMsでつくるServerless CI
fujioka6789
3
360
C#コードの結合を可視化する Roslyn解析による設計改善と リファクタリング判断
dora56
0
150
AI時代の「技術的負債」の変質ー概念の終焉と再解釈、エージェントと共に向かう先
nwiizo
1
2.9k
Featured
See All Featured
Why Our Code Smells
bkeepers
PRO
340
58k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
400
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Statistics for Hackers
jakevdp
799
230k
Believing is Seeing
oripsolob
1
220
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.2k
Git: the NoSQL Database
bkeepers
PRO
432
67k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.6k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.6k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
18k
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された場合
͓ΘΓ