Holding a lock across an await in Rust
tokio's Mutex may be held across an await point; the std one may not.
use std::sync::Arc;
use tokio::sync::Mutex;
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
let log = Arc::new(Mutex::new(Vec::new()));
let mut tasks = Vec::new();
for id in 0..3 {
let log = Arc::clone(&log);
tasks.push(tokio::spawn(async move {
let mut entries = log.lock().await;
sleep(Duration::from_millis(5)).await;
entries.push(id);
}));
}
for t in tasks {
t.await.unwrap();
}
let mut entries = log.lock().await.clone();
entries.sort();
println!("{:?}", entries);
}
How it works
- An async lock yields instead of blocking the thread.
- Use the std
Mutexwhen the critical section has noawait. Arcstill provides the shared ownership.
Keywords and builtins used here
Vecasyncawaitfnforinletmainmovemutuse
The run, in numbers
- Lines
- 26
- Characters to type
- 496
- Tokens
- 175
- Three-star pace
- 110 tpm
At the three-star pace of 110 tokens a minute, this run takes about 95 seconds.
Step 6 of 6 in Async with tokio, step 14 of 15 in Concurrency & async.