###### tags: `Rust` `Arc` `Mutex` `Sync` `Send` # マルチスレッディングのためのArc, Mutex # Arc\<T> すごく簡単なマルチスレッドの例 ```rust= fn main(){ let name = "John"; let t = thread::spawn(|| { thread::sleep(Duration::from_secs(1)); println!("hello {}", name); }); let _ = t.join(); } ``` - main() スレッドから、新たなスレッドが作られている。 - サブスレッドのクロージャーでは、 name 変数が借用されている。 - t.join() で、サブスレッドが終わるまで main() がまつ というような処理内容 これはコンパイルエラーになる ## 理由 サブスレッドとしてspawnされるクロージャーは、 'static な生存期限を持つ つまり、nameは自分の生存期限より長い時間借用される そのためエラー ## 解決策 : Arc\<T>を使う スマートポインターの一つ Atomicaly refference counter ひとかたまりの、分割できない参照カウンター ? という感じ - リソースを指すポインター - Arc::new(T) で作成されたリソースは、ヒープアロケートされる - リソースを参照している参照の数をカウントする。 - カウントがゼロになるまで、リソースは削除されないことを保証 - ゼロになったらリソースを開放 - 参照をclone()できる。 - クローンした参照は、別のスレッドでも利用できる。 - 参照カウントによりリソースの開放を管理するので、 - 生存期間が元のスレッドより長くなっても大丈夫 ## 使用例 ポイントは、使うときに clone() すること 下の例では、`{}`でブロックを作って、その中でクローン->move をすることで シャドーイングで作成した参照をクロージャーに移譲している。 ```rust= fn main() { // Arcで包む let enemy = Arc::new(Enemy { x: 0, y: 0}); { // 使う時に clone する let enemy = enemy.clone(); let _ = thread::spawn(move || { loop { thread::sleep(Duration::from_secs(1)); do_something(&enemy); } }); } let enemy = enemy.clone(); for _ in 0..5 { thread::sleep(Duration::from_secs(1)); println!("({},{})", enemy.x, enemy.y); } } ``` # Mutex Arc\<T>がスレッド間で参照を渡すときの、生存期間の問題を 解決することがわかった。 しかし、Arc\<T>でクローンできる参照はimutableである。 mutableな扱いをするときは、 Mutexで他のスレッドの利用をlockする。 スレッド間の参照受け渡し + リソースのロック Arc + Mutex ```rust= Arc::new(Mutex::new(resource)); ``` # Sync と Send それぞれ、特別なTraitの一つ 特別なtype - Box, RC, Pin, UnsafeCell, PhantomData 特別なtrait - Defef : * のオーバーロード - DerefMut : * のオーバーロードのmut版 - Drop : デストラクタ - Copy : 値コピーの実装 - Clone: Copyのsuper trait。Copy + Tupleコピー、Arrayコピーを実装 - Send : 別のスレッドへ値を安全に送る実装 - Sync : マルチスレッドで共有しても安全な型であることの実装。 - staticなimmutableアイテムには必ず実装されていなければならない
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up