rust-concurrency - 課題
概要
Rustの並行処理機能を学び、スレッドセーフなプログラムを実装する課題です。
マンダトリーパート
必須要件
- スレッド間のデータ共有
- メッセージパッシング
- 並列処理ユーティリティ
インターフェース
use std::sync::{Arc, Mutex, mpsc};
use std::thread;
/// スレッドセーフなカウンター
pub struct Counter {
count: Arc<Mutex<u64>>,
}
impl Counter {
pub fn new() -> Self;
pub fn increment(&self);
pub fn get(&self) -> u64;
}
/// チャネルベースのワーカー
pub fn spawn_workers<T, F, R>(
items: Vec<T>,
worker_count: usize,
process: F,
) -> Vec<R>
where
T: Send + 'static,
R: Send + 'static,
F: Fn(T) -> R + Send + Clone + 'static;
/// スレッドプール
pub struct ThreadPool {
workers: Vec<Worker>,
sender: mpsc::Sender<Job>,
}
impl ThreadPool {
pub fn new(size: usize) -> Self;
pub fn execute<F>(&self, f: F)
where
F: FnOnce() + Send + 'static;
}
/// 並列イテレータ風の処理
pub fn parallel_map<T, U, F>(items: Vec<T>, f: F) -> Vec<U>
where
T: Send + 'static,
U: Send + 'static,
F: Fn(T) -> U + Send + Sync + 'static;
使用例
// カウンター
let counter = Counter::new();
let handles: Vec<_> = (0..10).map(|_| {
let c = counter.clone();
thread::spawn(move || {
for _ in 0..100 {
c.increment();
}
})
}).collect();
for h in handles { h.join().unwrap(); }
assert_eq!(counter.get(), 1000);
// スレッドプール
let pool = ThreadPool::new(4);
pool.execute(|| println!("Task 1"));
pool.execute(|| println!("Task 2"));
ボーナスパート
ボーナス1: バリア同期
- 複数スレッドの同期ポイント
ボーナス2: 読み書きロック
- RwLock を使用した最適化
ボーナス3: アトミック操作
- ロックフリーカウンター
src/counter.rs- スレッドセーフカウンターsrc/channel.rs- チャネル処理src/pool.rs- スレッドプールCargo.tomlunsafeは使用不可- 外部クレート(rayon等)は使用不可