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
Catch Up Swift Concurrency Actor & Sendable
Search
tosshii
May 17, 2024
Programming
0
230
Catch Up Swift Concurrency Actor & Sendable
社内のiOS勉強会の発表資料「Catch Up Swift Concurrency Actor & Sendable」
tosshii
May 17, 2024
Tweet
Share
More Decks by tosshii
See All by tosshii
Qiita Hackathon: そこにAIはあるんか
toshiyana36
0
92
Other Decks in Programming
See All in Programming
“いい感じ“な定量評価を求めて - Four Keysとアウトカムの間の探求 -
nealle
0
250
GraphRAGの仕組みまるわかり
tosuri13
8
500
PicoRuby on Rails
makicamel
2
110
datadog dash 2025 LLM observability for reliability and stability
ivry_presentationmaterials
0
330
ASP.NETアプリケーションのモダナイズ インフラ編
tomokusaba
1
430
DroidKnights 2025 - 다양한 스크롤 뷰에서의 영상 재생
gaeun5744
3
340
今ならAmazon ECSのサービス間通信をどう選ぶか / Selection of ECS Interservice Communication 2025
tkikuc
20
3.8k
NPOでのDevinの活用
codeforeveryone
0
480
PipeCDのプラグイン化で目指すところ
warashi
1
230
Create a website using Spatial Web
akkeylab
0
310
すべてのコンテキストを、 ユーザー価値に変える
applism118
2
980
deno-redisの紹介とJSRパッケージの運用について (toranoana.deno #21)
uki00a
0
160
Featured
See All Featured
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
Music & Morning Musume
bryan
46
6.6k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.4k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
357
30k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
107
19k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
30
2.1k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
8
680
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
657
60k
Measuring & Analyzing Core Web Vitals
bluesmoon
7
490
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Transcript
Catch Up Actor & Sendable
学ぶこと 1. 2. 3. 4. データ競合 Actor Sendable Global ActorとMainActor
データ競合とは • • データ競合は以下の条件が揃うような事象 複数スレッドが、同時に共通の可変データに対してアクセス この時、アクセスのうち少なくとも1つは書き込み データ競合は、予測できない動作、メモリ破損、不安定なテスト、謎のクラッシュを引き起こす可 能性がある <- 再現・修正も大変
データ競合の例 • • 複数スレッドで並行して共通の可変データに対して書き込みを行なってしまっている 片方が1,もう片方が2を出力すべきだが、両方2を返してしまう可能性がある
これまでのデータ競合の防ぎ方 • • 以下の機能で排他制御を行う(共有されたデータに同時にアクセスできないようにする)ことでデータ 競合を防いでいた Lock Grand Central Dispatch (Serial
Dispatch Queue)
GCDでデータ競合を防ぐ例 queue.async { … } 内は直列で処理されるためデータ競合が起きない 上記はシンプルな例だが、処理が複雑になれば直列処理にする部分をより注意して実装しないといけない
そこでActorが登場 • • • • Actorとは: Actorは、共通の可変データを同期的に操作する仕組みを提供する型 Actorは、可変データへのアクセスが排他的に行われることをコンパイラーが強制 エラーが出ないように実装すれば基本的にデータ競合を防げる これがGCDではなくActorを使う大きな利点!
Actor Type • • • • • • • 特徴
参照型 プロパティへのアクセスが同期的に行われることが基本的にコンパイル時に保証 他の型(enum, sturct, class)と性質は似ている property, method, initializer, subscript, ... をもてる protocol に適合可能 extensionで拡張可能 継承は非サポート
先ほどの例をActorで書き換えた場合
Actorがデータ競合を防ぐ仕組み • • Actorインスタンスのメンバ(stored/computed property, method, subscript 等)は、デフォルト では「actor-isolated」 な定義として扱われる
actor-isolatedな定義は、Actorインスタンス内部(self)からのみ直接参照でき、外部から直接参照 しようとするとコンパイルエラーになる ← 可変データが保護されデータ競合を防ぐ
Actorのメンバを外部から参照する方法 • 1. • 2. 参照が許可されるパターン 同一モジュール内のActorの不可変な定義に対する参照 不可変であればデータ競合が起きないため 非同期呼び出し(await)による参照 Actorで非同期呼び出しを行うと、データ競合が起きないよう排他制御が行われる
Actorのメンバを外部から参照する方法 1. 2. 参照が許可されるパターン 同一モジュール内のActorの不可変な定義に対する参照 非同期呼び出し(await)による参照
補足: Actorの内部処理 > 各アクター・インスタンスには独自のシリアル・エグゼキューター(Structured Concurrency プ ロポーザルで記述)が含まれます。デフォルトのシリアル・エクゼキュータは、部分タスクを一度 に実行します。これは概念的にはシリアルの DispatchQueue に似ていますが、重要な違いがあり
ます:アクタを待っているタスクは、元々そのアクタを待っていたのと同じ順序で実行されること は保証されていません。Swift のランタイムシステムは、優先順位エスカレーションのような技術を 使用して、可能な限り優先順位の逆転を避けることを目的としています。したがって、ランタイム システムは、そのキューからアクタ上で実行する次のタスクを選択するときに、タスクの優先順位 を考慮します。これは、厳密に先入れ先出しのシリアル DispatchQueue とは対照的です。さらに、 Swift のアクターランタイムは、Swift の非同期関数を最大限に活用するために、Dispatch よりも軽 量なキューの実装を使用します。 https://github.com/apple/swift-evolution/blob/main/proposals/0306-actors.md#actor-isolation
actor-isolatedな定義をしたくない場合 • • 例として、ActorがHashableプロトコルに準拠させる場合を考える Hashableプロトコルのhash(into:)メソッドは同期呼び出しの必要あり
actor-isolatedな定義をしたくない場合 • nonisolatedキーワードをメソッドにつけると、メソッドがActor内部に定義されていても、 Actor外部として扱われる → 同期呼び出しが可能になる
Actor内でawaitする際は注意(Actor reentrancy) • 以下のケースでは出力はどうなるだろうか?
Actor内でawaitする際は注意(Actor reentrancy) • 以下のケースでは出力はどうなるだろうか? → Answer: 全て3が出力 (1,2,3と出力されない)
Actor内でawaitする際は注意(Actor reentrancy) • • Actorのメソッド内でawaitしてsuspendしている間、メソッドの実行が可能 (Actor reentrancy) 以下のケースではsuspendしている間にactor内の可変データの値が変化している
Actor内でawaitする際は注意(Actor reentrancy) • • • 注意すること Actor内でawaitしてsuspendしている間に、Actor内の可変データが変化していないか確認 なるべくActor内の可変状態の変更は同期処理で行う(awaitしない)
Actor内外の境界でやり取り可能なもの • • Actor内外の境界でやり取りするものはSendableである必要がある Sendableでないものをやりとりしようとした場合、コンパイルエラーになる
Sendableとは • • • • • • • Sendableとは: コピーすることで、ある並行性ドメインから別の並行性ドメインに安全に渡せるも
の Sendableになるもの 値型 アクター型 不変クラス 内部で同期的に処理されるクラス @Sendableでマークされた関数,クロージャー
Sendableの必要性 • • Actorインスタンスのメンバの種類によってはActor Isolationが崩れる 以下の例では可変データを持つItemクラスは参照型なので、Actor外部で状態変更ができてし まう(データ競合になり得る)
Sendableの必要性(型をSendableにする) • • 型をSendableプロトコルに準拠させると、コンパイラがSendableどうかチェックする structやclassの場合、保持するプロパティは全てSendableになっていないとコンパイルエラ ーになる
Sendableの必要性(関数,クロージャーをSendableにする) • • 関数,クロージャをSendableにする場合は@Sendableをつける @Sendableがついたクロージャーは、可変な値をキャプチャできず、キャプチャする値は Sendableでなければならない
struct vs class vs actor
Global Actor • Global Actorは、この Actor isolation によって得られる恩恵を、単一の Actorインスタンスの範 囲から、コード内に散らばったさまざまな型や関数,
モジュールの範囲まで広げるための仕組み
Main Actor • • Main Actorは、メインスレッドでの実行を保証するためのGlobal Actorの一種 GCDのDispatchQueue.main.asyncが不要になる
Reference • • • • • • • • https://developer.apple.com/documentation/swift/sendable
https://developer.apple.com/documentation/swift/actor https://github.com/apple/swift-evolution/blob/main/proposals/0306-actors.md https://github.com/apple/swift-evolution/blob/main/proposals/0302-concurrent-value-and- concurrent-closures.md https://docs.swift.org/swift-book/documentation/the-swift-programming- language/concurrency/ https://developer.apple.com/videos/play/wwdc2021/10133/ https://qiita.com/maiyama18/items/c815f13f17d8e4095f68 https://medium.com/@Lakshmnaidu/class-vs-struct-vs-actor-a105eb21fdae
None