並列で実行されているスレッド間で情報を受け渡す
グローバルなstatic変数を使うか、チャンネルを使う
チャンネルではメインスレッドとスレッドとの間で特定の型の値を受け渡す通信機構を提供する
let (tx, rx) = mpsc::channel();
tx.send(count).unwrap();
use std::thread; use std::time::Duration; use std::sync::mpsc; fn main(){ let (tx, rx) = mpsc::channel(); let th = thread::spawn(move || { let mut count = 0; for _i in 1..11 { count = count + 1; tx.send(count).unwrap(); } }); let mut cnt = 0; for _i in 1..11 { cnt = cnt + 1; thread::sleep(Duration::from_millis(100)); } th.join().unwrap(); let val = rx.recv().unwrap(); println!("カウンタ={}", cnt + val); println!("プログラム終了"); }
### 排他制御
複数のスレッドが同じ変数にアクセスすることを避ける方法
std::syncにあるっミューテックスという方法を使って、他のスレッドが変数の値を変更しないようにする
let counter = Arc::new(Mutex::new(0));
use std::thread; use std::time::Duration; use std::sync::{Mutex, Arc}; fn main(){ let counter = Arc::new(Mutex::new(0)); let counter1 = Arc::clone(&counter); let th1 = thread::spawn(mmove || { for _i in 1..11 { print("+"); let mut num = counter1.lock().unwrap(); *num += 1; thread::sleep(Duration::from_millis(100)); } }); let counter2 = Arc::clone(&counter); let th2 = thread::spawn(move || { for _i in 1..11 { let mut num = counter2.lock().unwrap(); *num += 1; print!("-"); thread::sleep(Duration::from_millis(100)); } }); th1.join().unwrap(); th2.join().unwrap(); println!("\ncounter={:?}", counter); }
アトミック
use std::thread; use std::time::Duration; use std::sync::atomic::{self, AtomicU32, Ordering}; static COUNTER: AtopmicU32 = AtomicU32::new(0); fn count_up(){ COUNTER.fetch_add(1, atomic::Ordering::SeqCst); } fn get_count() -> u32 { return COUNTER.load(Ordering::SeqCst); } fn main(){ let th1 = thread::spawn(mmove || { for _i in 1..11 { print("+"); count_up(); thread::sleep(Duration::from_millis(100)); } }); let th2 = thread::spawn(move || { for _i in 1..11 { print!("-"); count_up(); thread::sleep(Duration::from_millis(100)); } }); th1.join().unwrap(); th2.join().unwrap(); println!("\ncounter={}", get_count()); }