Rust学习笔记
Rust编程语言入门教程课程笔记
Lecture 16: Fearless Concurrency 无畏并发
src/main.rs
rust
use std::thread;
use std::time::Duration;
use std::sync::mpsc;
use std::sync::{Mutex, Arc};
fn main() {
//Using Threads to Run Code Simultaneously
//Creating a New Thread with spawn
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));
}
// output:
// hi number 1 from the main thread!
// hi number 1 from the spawned thread!
// hi number 2 from the main thread!
// hi number 2 from the spawned thread!
// hi number 3 from the main thread!
// hi number 3 from the spawned thread!
// hi number 4 from the main thread!
// hi number 4 from the spawned thread!
//In this run, the main thread printed first,
//even though the print statement from the spawned thread appears first in the code.
//And even though we told the spawned thread to print until i is 9,
//it only got to 5 before the main thread shut down.
//Waiting for All Threads to Finish Using join Handles
handle.join().unwrap();
let v = vec![1, 2, 3];
let handle = thread::spawn(move || {
println!("Here's a vector: {:?}", v);
});//move closure: v is moved into the closure
// drop(v); // oh no! v is moved into the thread
handle.join().unwrap();
//Using Message Passing to Transfer Data Between Threads
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let val = String::from("hi");
// tx.send(val).unwrap();
tx.send(val).unwrap();
// println!("val is {}", val); // error: value borrowed here after move
});
let received = rx.recv().unwrap();//recv blocks the main thread's execution and waits until a value is sent down the channel
println!("Got: {}", received);
//try_recv: without blocking
//Sending Multiple Values and Seeing the Receiver Waiting
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let vals = vec![
String::from("hello"),
String::from("from"),
String::from("the"),
String::from("thread"),];
for val in vals {
tx.send(val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});
for received in rx {
println!("Got: {}", received);
}
//Shared-State Concurrency
//Mutexes: Mutual Exclusion
//API: lock, unwrap, Mutex<T> (smart pointer)
let m = Mutex::new(5);
{
let mut num = m.lock().unwrap();
*num = 6;
// println!("m is {}", m); // error: cannot be formatted with the default formatter
}
println!("m is {:?}", m);
//Sharing a Mutex<T> Between Multiple Threads
let counter = Arc::new(Mutex::new(0));
//Arc<T> is an atomically reference counted type
//A: atomically, R: reference, C: counted
//API in Arc is the same as in Rc
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!("Result: {}", *counter.lock().unwrap());//Result: 10
//Extensible Concurrency with the Sync and Send Traits
//Send: ownership can be transferred between threads
//Sync: multiple threads can have references to the same value
//Implementing Send and Sync Manually Is Unsafe
}