Weekly Rust Trivia is a problem-oriented series of articles that assist developers while learning Rust. Every article solves simple, everyday development tasks using the Rust standard library or leveraging popular and proven crates.

Question: How to share state between threads in Rust?

In Rust, we have the ability to share data between threads by using concurrent data structures and synchronization tools provided by the Rust standard library. The most popular concurrent data structures in Rust include Arc (atomic reference counting) and Mutex (mutual exclusion). These allow multiple threads to access shared data in a safe and synchronized manner.

For demonstration purposes we’ll use a simple vector (vec) and share it between multiple background threads. Each background thread will push data to the state in a controlled and safe manner:

use std::sync::{Arc, Mutex};
use std::thread;
use std::time::SystemTime;

fn main() {
    let shared_state = Arc::new(Mutex::new(vec![]));
    let mut thread_handles = vec![];
    
    for _ in 0..10 {
        let thread_data = Arc::clone(&shared_state);
        let handle = thread::spawn(move || {
            let mut state = thread_data.lock().unwrap();
            let now = SystemTime::now()
                .duration_since(SystemTime::UNIX_EPOCH)
                .unwrap()
                .as_secs();
            state.push(now);
        });
        thread_handles.push(handle);
    }

    // Wait for all threads to complete
    for handle in thread_handles {
        handle.join().unwrap();
    }

    let final_state = shared_state.lock().unwrap();
    println!("State: {:?}", *final_state);
}

When executing the sample above, we will see the following being printed to stdout (Obviously, actual values will differ slightly):

State: [1690192544, 1690192544, 1690192544, 1690192544, 1690192544, 1690192544,
    1690192544, 1690192544, 1690192544, 1690192544]