Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
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
250
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
99
Other Decks in Programming
See All in Programming
非同期処理の迷宮を抜ける: 初学者がつまづく構造的な原因
pd1xx
1
730
AIエンジニアリングのご紹介 / Introduction to AI Engineering
rkaga
8
3k
FluorTracer / RayTracingCamp11
kugimasa
0
240
リリース時」テストから「デイリー実行」へ!開発マネージャが取り組んだ、レガシー自動テストのモダン化戦略
goataka
0
130
まだ間に合う!Claude Code元年をふりかえる
nogu66
5
850
ELYZA_Findy AI Engineering Summit登壇資料_AIコーディング時代に「ちゃんと」やること_toB LLMプロダクト開発舞台裏_20251216
elyza
2
260
Python札幌 LT資料
t3tra
3
430
AIコーディングエージェント(Gemini)
kondai24
0
240
TUIライブラリつくってみた / i-just-make-TUI-library
kazto
1
390
著者と進める!『AIと個人開発したくなったらまずCursorで要件定義だ!』
yasunacoffee
0
150
re:Invent 2025 のイケてるサービスを紹介する
maroon1st
0
130
AIの誤りが許されない業務システムにおいて“信頼されるAI” を目指す / building-trusted-ai-systems
yuya4
6
3.7k
Featured
See All Featured
Into the Great Unknown - MozCon
thekraken
40
2.2k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
54k
Building Flexible Design Systems
yeseniaperezcruz
330
39k
Documentation Writing (for coders)
carmenintech
77
5.2k
Principles of Awesome APIs and How to Build Them.
keavy
127
17k
[SF Ruby Conf 2025] Rails X
palkan
0
540
A Tale of Four Properties
chriscoyier
162
23k
GitHub's CSS Performance
jonrohan
1032
470k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.3k
Designing Experiences People Love
moore
143
24k
Building an army of robots
kneath
306
46k
The Cult of Friendly URLs
andyhume
79
6.7k
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