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
Building a Modern Day E-commerce SEO Strategy
aleyda
38
6.9k
The Language of Interfaces
destraynor
154
24k
Automating Front-end Workflow
addyosmani
1366
200k
Practical Orchestrator
shlominoach
186
10k
Keith and Marios Guide to Fast Websites
keithpitt
409
22k
Imperfection Machines: The Place of Print at Facebook
scottboms
265
13k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5k
A designer walks into a library…
pauljervisheath
204
24k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
25
1.8k
Making the Leap to Tech Lead
cromwellryan
133
8.9k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
YesSQL, Process and Tooling at Scale
rocio
169
14k
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)を使っていこう