並行性への恐怖なし
並行性シリーズへようこそ!Rust の並行プログラミングへのアプローチは革命的です。コードが実行される前にデータ競合を防ぎ、コンパイル時にスレッド安全性を保証します。
並行性への恐怖とは?
並行性への恐怖とは、心配せずに並行コードを書くことができることを意味します:
- データ競合 - 2 つのスレッドが同時に同じデータにアクセス
- 競合状態 - 出力が実行順序に依存
- メモリ安全性の問題 - 並行コードでの無効なメモリアクセス
Rust は以下を通じてこれを実現します:
- 所有権システム - 安全なメモリアクセスを強制
- 型システム -
SendおよびSyncトレイト - 借用チェッカー - コンパイル時に並行アクセスを検証
学習ルート
mermaid
graph LR
A[並行性の基礎] --> B[並行性パターン]
B --> C[非同期ランタイム]
A --> A1[スレッド]
A --> A2[メッセージパッシング]
A --> A3[共有状態]
B --> B1[スレッドプール]
B --> B2[チャネルパターン]
B --> B3[アクターモデル]
C --> C1[Tokio]
C --> C2[Async-std]
C --> C3[Futures]コア概念
Send トレイト
ある型がスレッド間で安全に転送できる場合、Send です。
rust
use std::thread;
fn main() {
let v = vec![1, 2, 3];
let handle = thread::spawn(move || {
println!("ここにベクター: {:?}", v);
});
handle.join().unwrap();
}Sync トレイト
ある型の参照がスレッド間で安全に共有できる場合、Sync です。
rust
use std::sync::Arc;
use std::thread;
fn main() {
let data = Arc::new(vec![1, 2, 3]);
for i in 0..3 {
let data = Arc::clone(&data);
thread::spawn(move || {
println!("スレッド {} が見る: {:?}", i, data);
});
}
}並行性モデル
1. メッセージパッシング
「コミュニケーティング・シーケンシャル・プロセス」 - スレッドはメッセージを送信して通信します。
rust
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let val = String::from("こんにちは");
tx.send(val).unwrap();
});
let received = rx.recv().unwrap();
println!("受け取った: {}", received);
}2. 共有状態
複数のスレッドが同期されたデータへのアクセスを共有します。
rust
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("結果: {}", *counter.lock().unwrap());
}まとめ
Rust の並行性モデルは、安全かつ効率的な並行プログラミングを可能にします。
次のステップ:
- スレッドの基礎 を学ぶ
- メッセージパッシング を探索する
- 非同期プログラミング を勉強する