How can I mutably share an i32 between threads?

前端 未结 2 1219
别跟我提以往
别跟我提以往 2020-12-07 04:37

I\'m new to Rust and threading and I\'m trying to print out a number while adding to it in another thread. How can I accomplish this?

use std::thread;
use st         


        
2条回答
  •  爱一瞬间的悲伤
    2020-12-07 05:09

    Please read the "Shared-State Concurrency" chapter of The Rust Book, it explains how to do this in detail.

    In short:

    1. Your program does not work because num is copied, so output() and the thread operate on different copies of the number. The Rust compiler will fail to compile with an error if num is not copyable.
    2. Since you need to share the same variable between multiple threads, you need to wrap it in an Arc (atomic reference-counted variable)
    3. Since you need to modify the variable inside the Arc, you need to put it in a Mutex or RwLock. You use the .lock() method to obtain a mutable reference out of a Mutex. The method will ensure exclusive access across the whole process during the lifetime of that mutable reference.
    use std::sync::{Arc, Mutex};
    use std::thread;
    use std::time::Duration;
    
    fn main() {
        let num = Arc::new(Mutex::new(5));
        // allow `num` to be shared across threads (Arc) and modified
        // (Mutex) safely without a data race.
    
        let num_clone = num.clone();
        // create a cloned reference before moving `num` into the thread.
    
        thread::spawn(move || {
            loop {
                *num.lock().unwrap() += 1;
                // modify the number.
                thread::sleep(Duration::from_secs(10));
            }
        });
    
        output(num_clone);
    }
    
    fn output(num: Arc>) {
        loop {
            println!("{:?}", *num.lock().unwrap());
            // read the number.
            //  - lock(): obtains a mutable reference; may fail,
            //    thus return a Result
            //  - unwrap(): ignore the error and get the real
            //    reference / cause panic on error.
            thread::sleep(Duration::from_secs(5));
        }
    }
    

    You may also want to read:

    • Why does Rust have mutexes and other sychronization primitives, if sharing of mutable state between tasks is not allowed?
    • What happens when an Arc is cloned?
    • How do I share a mutable object between threads using Arc? (for why we need Arc> instead of Arc)
    • When would you use a Mutex without an Arc? (for why we need Arc> instead of Mutex)

提交回复
热议问题