Rust8.2 Fearless Concurrency

Rust学习笔记

Rust编程语言入门教程课程笔记

参考教材: The Rust Programming Language (by Steve Klabnik and Carol Nichols, with contributions from the Rust Community)

Lecture 16: Fearless Concurrency 无畏并发

src/main.rs

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 (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 Between Multiple Threads
    let counter = Arc::new(Mutex::new(0));
    //Arc 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
}

你可能感兴趣的:(rust,笔记)