use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let counter = Arc::new(Mutex::new(0),|counter|{
// on changed event handler
// counter is automatically locked and can be updated too
println!("counter: {}", counter);
}
);
let mut handles = vec![];
for _ in 0..10 {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Result: {}", *counter.lock().unwrap());
}
Why isn't there an event when a mutex variable is changed ? Something like in my example.
Thank you in advance for your answers and sorry if this is a stupid question or impossible to achieve.
Well, Condvar is more intended to manage threads in my opinion and you need a blocking event loop to listen for the event which is not the case in my example.
The goal is to track mutex updates from the mutex created thread, not to notify when a thread can continue its task.
Rust doesn't have a runtime where you dynamically register and subscribe to events for everything in the standard library or anything like that. If you need such functionality, you'll need a crate that provides it or to build it yourself.
Perhaps you want newtypes around Mutex and MutexGuard so that everytime one of your wrapped MutexGuards is dropped, it invokes a callback before releasing the underlying guard.
Wonderfull answer with playground as bonus !!! Many thanks.
My only missing feature is that the callback is always running from child threads and my final goal would be to run it from the main thread without any event loop, but it seems impossible: my first feeling was that the mutex was managed from the main thread and this is not the case
Mutexes (muteci?) aren't "managed" in the userspace at all.
If you want to react to events, you have to have some sort of an event loop, probably using channels (which is more or less a fifo queue and a condvar).