Blog Datasheets Home About me Clients My work Services Contact

G2Labs Grzegorz Grzęda

Concurrency in Rust

January 28, 2024

Understand Concurrency

Rust’s Approach to Concurrency

Key Concepts in Rust Concurrency

  1. Ownership and Type Checking: The ownership model plays a crucial role in concurrency. Rust’s compile-time ownership checks prevent data races, a common issue in concurrent programming.

  2. Threads: Rust provides a way to run code on different threads. The std::thread module allows you to create threads and execute code in parallel.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    use std::thread;
    
    fn main() {
        let handle = thread::spawn(|| {
            // code to run in a new thread
        });
    
        // wait for the thread to complete
        handle.join().unwrap();
    }
    
  3. Message Passing for Communication: Rust encourages the use of message passing to transfer data between threads. This is done using channels provided by the std::sync::mpsc module (multi-producer, single-consumer).

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
    use std::sync::mpsc;
    use std::thread;
    
    fn main() {
        let (tx, rx) = mpsc::channel();
    
        thread::spawn(move || {
            tx.send("Hello").unwrap();
        });
    
        let received = rx.recv().unwrap();
        println!("Received: {}", received);
    }
    
  4. Shared State Concurrency: Rust also supports shared state concurrency, but it’s done in a way to ensure safety. The Arc (Atomic Reference Counted) and Mutex (mutual exclusion) types in the std::sync module are used to safely share and modify data between threads.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    use std::sync::{Arc, Mutex};
    use std::thread;
    
    fn main() {
        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 || {
                let mut num = counter.lock().unwrap();
                *num += 1;
            });
            handles.push(handle);
        }
    
        for handle in handles {
            handle.join().unwrap();
        }
    
        println!("Result: {}", *counter.lock().unwrap());
    }
    
  5. Sync and Send Traits: These are marker traits in Rust that allow safe concurrency. Send indicates that ownership of the type implementing it can be transferred between threads. Sync indicates that it is safe for the type implementing it to be referenced from multiple threads.

Transition Tips for C Developers

Concurrency in Rust is a vast topic and crucial for writing high-performance applications. Its approach to managing concurrent operations is designed to minimize the risk of race conditions and other concurrency-related bugs that are common in languages like C.


➡️ Introduction to AVR Assembly Language Programming with Atmega-328


⬅️ Exploring the Features and Architecture of AVR Atmega-328


Go back to Posts.