use std::sync::{Arc, Mutex, RwLock};
use std::thread;
pub fn safe_concurrent_counter() {
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter_clone = Arc::clone(&counter);
let handle = thread::spawn(move || {
for _ in 0..1000 {
let mut num = counter_clone.lock().unwrap();
*num += 1;
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Final counter value: {}", *counter.lock().unwrap());
}
pub fn safe_read_write_access() {
let data = Arc::new(RwLock::new(vec![1, 2, 3]));
let mut handles = vec![];
for i in 0..5 {
let data_clone = Arc::clone(&data);
let handle = thread::spawn(move || {
let read_guard = data_clone.read().unwrap();
println!("Reader {}: {:?}", i, *read_guard);
});
handles.push(handle);
}
let data_clone = Arc::clone(&data);
let writer_handle = thread::spawn(move || {
let mut write_guard = data_clone.write().unwrap();
write_guard.push(4);
println!("Writer added element");
});
handles.push(writer_handle);
for handle in handles {
handle.join().unwrap();
}
}
struct SendableData {
value: i32,
}
struct NotSendable {
ptr: *mut i32, }
pub fn thread_safety_enforced() {
let sendable = SendableData { value: 42 };
thread::spawn(move || {
println!("Value in thread: {}", sendable.value);
});
}
use std::sync::mpsc;
pub fn safe_message_passing() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
for i in 0..5 {
tx.send(i).unwrap();
}
});
for received in rx {
println!("Received: {}", received);
}
}
use std::sync::atomic::{AtomicUsize, Ordering};
pub fn safe_atomic_operations() {
let counter = Arc::new(AtomicUsize::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter_clone = Arc::clone(&counter);
let handle = thread::spawn(move || {
for _ in 0..1000 {
counter_clone.fetch_add(1, Ordering::SeqCst);
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Atomic counter: {}", counter.load(Ordering::SeqCst));
}
pub fn scoped_threads_safe() {
let mut data = vec![1, 2, 3];
thread::scope(|s| {
s.spawn(|| {
println!("Data length: {}", data.len());
});
s.spawn(|| {
println!("Data: {:?}", data);
});
});
data.push(4); }
#[cfg(test)]
mod tests {
use super::*;
use std::sync::atomic::Ordering;
#[test]
fn test_mutex_correctness() {
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter_clone = Arc::clone(&counter);
let handle = thread::spawn(move || {
for _ in 0..100 {
*counter_clone.lock().unwrap() += 1;
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
assert_eq!(*counter.lock().unwrap(), 1000);
}
#[test]
fn test_atomic_correctness() {
let counter = Arc::new(AtomicUsize::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter_clone = Arc::clone(&counter);
let handle = thread::spawn(move || {
for _ in 0..100 {
counter_clone.fetch_add(1, Ordering::SeqCst);
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
assert_eq!(counter.load(Ordering::SeqCst), 1000);
}
#[test]
fn test_message_passing() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
tx.send(42).unwrap();
});
let received = rx.recv().unwrap();
assert_eq!(received, 42);
}
#[test]
fn test_rwlock() {
let data = Arc::new(RwLock::new(vec![1, 2, 3]));
let data_clone = Arc::clone(&data);
let handle = thread::spawn(move || {
let read = data_clone.read().unwrap();
read.len()
});
let len = handle.join().unwrap();
assert_eq!(len, 3);
}
}