多线程
闭包
Rust中,闭包(Closure)是一种函数对象。
闭包的使用场景:
- 迭代器:迭代器需要返回一个函数对象,用于迭代。
- 事件处理:在事件处理中,闭包可以作为回调函数,用于处理事件。
- 线程:在多线程中,闭包可以作为线程函数,用于创建线程。
rust
fn main() {
let add = |a, b| a + b;
println!("{}", add(1, 2));
}
rust
fn main() {
let a = 1;
let b = 2;
// Fn闭包:通过引用捕获变量(不可变借用)
let add = |x| a + x;
// FnMut闭包:通过可变引用捕获变量(可变借用)
let mut multiply = |x| {
a * b * x
};
// FnOnce闭包:通过值捕获外部变量(所有权转移)
let divide = move |x| x / b;
println!("{}", add(3));
println!("{}", multiply(3));
println!("{}", divide(3));
}
rust
// 函数参数 (推荐此种写法)
fn apply<F>(f: F)
where
F: Fn(),
{
f();
}
// 返回闭包
fn create_closure() -> impl Fn() {
let x = 5;
move || println!("the value of x is {}", x)
}
fn main() {
// 闭包作为参数
let print_hello = || println!("hello, world!");
apply(print_hello);
// 返回闭包
let closure = create_closure();
closure();
}
多线程
简单示例
rust
use std::thread;
use std::time::Duration;
fn main() {
let handle = thread::spawn(|| {
for i in 1..10 {
println!("hi number {} from the spawned thread!", i);
thread::sleep(Duration::from_millis(1));
}
});
for i in 1..5 {
println!("hi number {} from the main thread!", i);
thread::sleep(Duration::from_millis(1));
}
}
bash
hi number 1 from the main thread!
hi number 2 from the main thread!
hi number 1 from the spawned thread!
hi number 2 from the spawned thread!
hi number 3 from the spawned thread!
hi number 4 from the spawned thread!
hi number 5 from the spawned thread!
hi number 6 from the spawned thread!
hi number 7 from the spawned thread!
hi number 8 from the spawned thread!
hi number 9 from the spawned thread!
hi number 3 from the main thread!
hi number 4 from the main thread!
bash
hi number 1 from the main thread!
hi number 2 from the main thread!
hi number 3 from the main thread!
hi number 4 from the main thread!
hi number 1 from the spawned thread!
通过Builder构建线程
rust
use std::thread;
use std::time::Duration;
fn main() {
let handle = thread::Builder::new()
.name("my-thread".to_string()) // 设置线程名称
.stack_size(10 * 1024) // 设置线程栈大小
.spawn(|| {
for i in 1..5 {
println!("hi number {} from the spawned thread!", i);
thread::sleep(Duration::from_millis(1));
}
});
// 等待线程结束
handle.unwrap().join().unwrap();
}
bash
hi number 1 from the spawned thread!
hi number 2 from the spawned thread!
hi number 3 from the spawned thread!
hi number 4 from the spawned thread!
子线程传值给主线程
rust
use std::thread;
use std::time::Duration;
fn main() {
let sub_thread = thread::spawn(|| {
println!("sub thread");
println!("sub thread sleep 2 sec");
thread::sleep(Duration::from_secs(2));
println!("sub thread end");
"hello"
});
let result = sub_thread.join().unwrap();
println!("{}", result); // hello
}
rust
use std::thread;
fn my_func(n: u32) -> u32 {
n + 1
}
fn main() {
let handle = thread::spawn(|| my_func(1));
let result = handle.join().expect("Cloud not join thread");
println!("{}", result);
}
使用其他线程数据
rust
use std::thread;
fn main() {
let data = "hello";
let handle = thread::spawn(|| {
println!("data: {}", data);
// 编译不通过
// help: to force the closure to take ownership of `data` (and any other referenced variables), use the `move` keyword
});
handle.join().unwrap();
}
rust
use std::thread;
fn main() {
let data = "hello";
let handle = thread::spawn(move || {
println!("data: {}", data);
});
handle.join().unwrap();
}
rust
use std::thread;
fn main() {
let v = vec![1, 3, 5, 7, 9, 11];
let mut items = Vec::new();
for i in v {
// 这里必须添加move,转移所有权
let t = thread::spawn(move || {
i * i
});
items.push(t);
}
// 执行
for item in items {
println!("{:?}", item.join().unwrap());
}
}
线程函数
rust
use std::thread;
// 斐波那契数列
fn fibonacci(n: u64) -> u64 {
match n {
0 => 0,
1 => 1,
_ => fibonacci(n - 1) + fibonacci(n - 2),
}
}
fn main() {
let handle = thread::spawn(|| {
let f = fibonacci(20);
println!("fibonacci(20) = {}", f);
f
});
println!("main thread");
let v = handle.join().expect("thread panicked");
println!("main thread end");
println!("the value is {}", v);
}
获取线程信息
rust
fn main() {
println!("{}", std::thread::available_parallelism().unwrap())
}
rust
// 主线程ID
println!("{:?}", std::thread::current().id()); // ThreadId(1)
let handle = std::thread::spawn(|| {
// 子线程ID
println!("{:?}", std::thread::current().id()); // ThreadId(2)
});
handle.join().unwrap();
线程间通信
rust
use std::thread;
use std::sync::{Arc, Mutex};
fn main() {
// Mutex 互斥锁
// Arc 原子引用计数器
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 || {
// 获取Mutex锁
let mut num = counter.lock().unwrap();
// 修改计数器的值
*num += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Result: {}", *counter.lock().unwrap());
}