How to unlock a `Mutex` mannually?

I have the following code:

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?

you can do std::mem::drop(guard)

2 Likes

...and then reacquire the lock.

1 Like

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 :+1:.

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.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.