Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
DispatchQueue.syncが動作するスレッド
Search
Iceman
October 29, 2018
0
300
DispatchQueue.syncが動作するスレッド
Iceman
October 29, 2018
Tweet
Share
More Decks by Iceman
See All by Iceman
わいわいswift#39 Swiftの型をTypeScriptで表す
sidepelican
0
250
わいわいswiftc#35夢が広がる!コード生成でどこでもSwift
sidepelican
0
330
元ゲーム開発者が贈る描画パフォーマンス改善 / Rendering performance improvement from a game developer
sidepelican
4
1.4k
わいわいswiftc#19Genericsの特殊化
sidepelican
0
380
わいわいswiftc#17Genericsの特殊化
sidepelican
0
55
SwiftUI: 更新検知と値の生存期間
sidepelican
2
940
クックパッドiOSアプリのパフォーマンス改善
sidepelican
0
680
Featured
See All Featured
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
It's Worth the Effort
3n
183
27k
Designing for humans not robots
tammielis
250
25k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Speed Design
sergeychernyshev
24
610
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
Imperfection Machines: The Place of Print at Facebook
scottboms
265
13k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
26
1.4k
Transcript
DispatchQueue.sync が動作するスレッド
自己紹介 Twitter: Iceman (@iceman5499) Github:okamura (sidepelican) クックパッド株式会社 名前とアイコンとIDがブレブレ太郎なので最近はIcemanで統一しよ うと考えてます
DispatchQueueでありがちなデッドロック 軽い気持ちで呼んだ関数が内部で DispatchQueue.sync を使っていた
便利関数が用意される
これでクラッシュしない! めでたしめでたし
しかしここで疑問が 次のようなコードを実行するとき
None
しかしここで疑問が 実際に実行するとクラッシュしない この場合 Thread.isMainThread は true を返す myqueue の中から呼んでいるのに、なぜ? (この時点で僕は勘違いをしています)
apple/swift‑corelibs‑libdispatch
デッドロックを発生させてエラーからソースをたどる dispatch_sync called on queue already owned by current thread
というエラー文をswift‑corelibs‑libdispatchから grep → 出ない
あった( _dispatch_sync_wait ) C++の文字列リテラルは空白や改行があれば結合されるので、そこ で分かれていた
デッドロック判定処理をたどる _dq_state_drain_locked_by が判定しているっぽい typedef uint32_t dispatch_tid; typedef uint32_t dispatch_lock;
#define DLOCK_OWNER_MASK ((dispatch_lock)0xfffffffc) C にありがちなビット演算 dq_state と tid の下位3~32bitが同一かどうかで比較されてる dq_state
は DispatchQueue が管理している値っぽいので、 tid が何か分かれば良さそう
_dispatch_sync_waitに戻る tid は _dispatch_tid_self() から来てるっぽい
#define _dispatch_tid_self() \ ((dispatch_tid)_dispatch_thread_port()) #define _dispatch_thread_port() \ pthread_mach_thread_np(_dispatch_thread_self()) ようやく見慣れた関数が出てくる (
pthread_self ) OSによって分岐しているが、実態はpthreadのスレッドID(あるい は同等にみなせる代物)っぽい
_dispatch_sync_waitに戻る sync処理を行う対象のスレッドが現在のスレッドならデッドロック と判定しクラッシュさせている
最初の疑問に戻り、なぜrunOnMainThreadは問題なさ そうなのか
None
そもそもの勘違い DispatchQueue はそれぞれが専用のスレッドを持っていてその中 でのみ動作するものだと思いこんでいた これだとconcurrent queueは何者やねん!ってなる
最後に 事の発端となった DispatchQueue.main.sync だが、そもそもこ れをしなきゃいけない場面はほぼないはず 適切に DispatchQueue (や、Lock)を使っていこう