use std::sync::Arc; use tokio::sync::Mutex; use tokio::time::{sleep, Duration}; // Our shared context that will be accessed by all workers #[derive(Debug)] struct SharedContext { counter: i32, last_updated_by: String, } // Worker function that will run asynchronously async fn worker(id: i32, context: Arc>) { for i in 1..=5 { // Simulate some async work sleep(Duration::from_secs(1)).await; // Lock the context to modify it let mut locked_context = context.lock().await; locked_context.counter += 1; locked_context.last_updated_by = format!("Worker {}", id); println!( "Worker {} (iteration {}): Updated counter to {}", id, i, locked_context.counter ); } } #[tokio::main] async fn main() { // Create shared context wrapped in Arc (Atomic Reference Counting) and Mutex let shared_context = Arc::new(Mutex::new(SharedContext { counter: 0, last_updated_by: String::new(), })); // Create three worker tasks let mut handles = vec![]; for worker_id in 1..=3 { // Clone the Arc to share ownership of the context let context_clone = Arc::clone(&shared_context); // Spawn a new async task let handle = tokio::spawn(async move { worker(worker_id, context_clone).await; }); handles.push(handle); } // Wait for all workers to complete for handle in handles { handle.await.unwrap(); } // Print final state let final_context = shared_context.lock().await; println!("\nFinal state:"); println!("Counter: {}", final_context.counter); println!("Last updated by: {}", final_context.last_updated_by); }