use std::sync::Mutex;
fn wait_notify(data: &(Mutex<i32>, Condvar)) {
let mut guard = data.0.lock().unwrap();
let cv = &data.1;
loop {
guard = cv.wait(guard).unwrap();
let got_data = guard.clone();
calc_data(&got_data);
}
}
fn calc_data(data: &i32) {
println!("{}", data);
std::thread::sleep(Duration::from_secs(100));
}
The function wait_notify has a parameter data: &(Mutex<i32>, Convar), which is shared by many threads. Each of the threads is waiting for Condvar to notify, and the function calc_data take long time to finish. So I'm trying to unlock the guard right after the line let got_data = guard.clone(); (before the line calc_data(&got_data);), so that once I got the i32, other threads can use the inner value i32 from Mutex<i32> before I call calc_data. What should I do?
Thanks for you reply, I test it, it works fine. And I test the following, it also works fine:
use std::sync::Condvar;
use core::time::Duration;
use std::sync::Mutex;
fn wait_notify(data: &(Mutex<i32>, Condvar)) {
let cv = &data.1;
loop {
guard = cv.wait(data.0.lock().unwrap()).unwrap();
let got_data = guard.clone();
drop(guard);
calc_data(&got_data);
}
}
fn calc_data(data: &i32) {
println!("{}", data);
std::thread::sleep(Duration::from_secs(100));
}
In your code, after the 5th line let mut guard = data.0.lock().unwrap();, the data is locked by thread 1, and at the same time, thread 2 is also trying to get the lock, but the lock is acquired by thread 1, so thread 2 is waiting.
Then by arriving at 8th line, thread 1 drop the old guard and get a new guard, so this is the time when thread 1 release the lock and thread 2 acquire the lock.
Is my understanding about the process of function wait_notify from your code right? Is it the same for the code above?
Ah yeah, yours is effectively the same as mine but more robust to changes .
There's no guarantee which thread gets the lock but if there's awhile between thread 1 dropping and then trying to get the lock again, while another thread is blocked on it, it will likely be the other thread.