Skip to content

多线程

use std::thread;
fn main() {
let handle = thread::spawn(|| {
println!("Hello from the thread!");
});
handle.join().unwrap();
}
use std::thread;
fn main() {
let person = Person {
name: String::from("John"),
};
// 使用 scope 来管理线程的生命周期
thread::scope(|s| {
s.spawn(|| {
// person 借用
println!("Hello, {:?}", person);
});
});
}
#[derive(Debug)]
struct Person {
name: String,
}
use std::sync::{Arc, Mutex, mpsc};
use std::time::Instant;
use std::{any, thread};
const TOTAL: u64 = 1000000000;
fn main() {
count_time(serialized_calculate);
count_time(parallel_calculate);
count_time(scoped_calculate);
count_time(channel_calculate);
}
fn count_time<F: FnOnce()>(f: F) {
let name = any::type_name::<F>();
let start = Instant::now();
f();
println!("[{name}] 总耗时: {} ms", start.elapsed().as_millis());
}
// 单线程计算
fn serialized_calculate() {
let mut sum = 0;
for i in 0..TOTAL {
sum += i;
}
println!("sum: {}", sum);
}
// 多线程计算
fn parallel_calculate() {
let chunk_size = TOTAL / 16;
let sum = Arc::new(Mutex::new(0));
let mut handles = vec![];
for i in 0..16 {
let start = i * chunk_size;
let end = if i == 15 { TOTAL } else { (i + 1) * chunk_size };
let sum_clone = Arc::clone(&sum);
let handle = thread::spawn(move || {
let mut local_sum = 0;
for i in start..end {
local_sum += i;
}
let mut sum = sum_clone.lock().unwrap();
*sum += local_sum;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("sum: {}", sum.lock().unwrap());
}
// 作用域线程计算
fn scoped_calculate() {
let chunk_size = TOTAL / 16;
let sum = Mutex::new(0);
thread::scope(|scope| {
for i in 0..16 {
let start = i * chunk_size;
let end = if i == 15 { TOTAL } else { (i + 1) * chunk_size };
let sum_ref = &sum;
scope.spawn(move || {
let mut local_sum = 0;
for i in start..end {
local_sum += i;
}
let mut sum = sum_ref.lock().unwrap();
*sum += local_sum;
});
}
});
println!("sum: {}", sum.lock().unwrap());
}
// 使用通道实现
fn channel_calculate() {
let chunk_size = TOTAL / 16;
let (tx, rx) = mpsc::channel();
for i in 0..16 {
let start = i * chunk_size;
let end = if i == 15 { TOTAL } else { (i + 1) * chunk_size };
let tx = tx.clone();
thread::spawn(move || {
let mut local_sum = 0;
for i in start..end {
local_sum += i;
}
tx.send(local_sum).unwrap();
});
}
drop(tx);
let mut sum = 0;
while let Ok(local_sum) = rx.recv() {
sum += local_sum;
}
println!("sum: {}", sum);
}