Concurrency in Rust
Rust provides powerful tools for concurrent programming, including threads, channels, and asynchronous tasks.
Threads
Use the std::thread
module to create and manage threads.
use std::thread;
fn main() {
let handle = thread::spawn(|| {
println!("Hello from a thread!");
});
handle.join().unwrap();
}
Mutex and Arc
Use Mutex
and Arc
to safely share data between threads.
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());
}
Channels
Use channels to communicate between threads.
use std::sync::mpsc;
use std::thread;
fn main() {
let (sender, receiver) = mpsc::channel();
thread::spawn(move || {
sender.send("Hello from the thread!").unwrap();
});
let message = receiver.recv().unwrap();
println!("Received: {}", message);
}
Thread Pools
Use thread pools to manage multiple threads efficiently.
use std::sync::mpsc;
use std::thread;
fn main() {
let (sender, receiver) = mpsc::channel();
for i in 0..4 {
let sender = sender.clone();
thread::spawn(move || {
sender.send(i).unwrap();
});
}
for _ in 0..4 {
println!("Received: {}", receiver.recv().unwrap());
}
}
Async/Await
Use the async
and await
keywords for asynchronous programming.
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
println!("Starting...");
sleep(Duration::from_secs(2)).await;
println!("Done!");
}
Async Channels
Use asynchronous channels with tokio
for non-blocking communication.
use tokio::sync::mpsc;
#[tokio::main]
async fn main() {
let (mut sender, mut receiver) = mpsc::channel(32);
tokio::spawn(async move {
sender.send("Hello from async channel!").await.unwrap();
});
let message = receiver.recv().await.unwrap();
println!("Received: {}", message);
}
Error Handling in Concurrency
Handle errors in concurrent Rust programs using Result
and unwrap
.
use std::thread;
fn main() {
let handle = thread::spawn(|| {
let result: Result<(), &str> = Err("Something went wrong!");
result.unwrap();
});
if let Err(e) = handle.join() {
println!("Thread panicked: {:?}", e);
}
}
Interactive Code Examples
Try running these examples in your Rust environment to see how they work!
// Interactive Example
use std::thread;
fn main() {
let handle = thread::spawn(|| {
println!("Hello from a thread!");
});
handle.join().unwrap();
}
Practice Problems
Test your understanding with these practice problems:
- Write a Rust program to create two threads that increment a shared counter using
Mutex
. - Write a Rust program to send multiple messages between threads using channels.
- Write a Rust program to simulate a task queue using a thread pool.