I am looking for a synchronization thingie that will let zero or more threads wait, with a timeout, until some other thread pokes them to go.
I was thinking I would use a
std::sync::semaphore, but I want a timeout and I don't see that that semaphore has a timeout. Looking around more I see
std::sync::Condvar, and it has a timeout!
Cool. As I am wiring it up and wondering when to set and clear my boolean var I realize that I don't need the var part of a condvar at all, I only need the one-to-many wake up, with a timeout.
What should I be using for this? Condvar?
You need at least a boolean value (in the Mutex) that can be checked to guard against spurious wakeups, as described here and as shown in the example.
Note that this function is susceptible to spurious wakeups. Condition variables normally have a boolean predicate associated with them, and the predicate must always be checked each time this function returns to protect against spurious wakeups.
In my case my threads are already getting "spurious" wakeups in sense that only one will handle the work but, they all need to be awakened to check just in case. So handling an extra wake up in addition to the ones I already handle…is no problem.
Playing with it more I need at least a
MutexGuard to pass to the the
wait_timeout() function, so putting a boolean inside is kinda minimal. Um, actually I can put a
() in there and call it
_dummy every time I need to mention it.
I am liking Rust. This feature I just added? I was doing something new so I referred to documentation…to a point. I quickly started typing, a little wise about what I added first, and asking the compiler along the way. Thinking, typing more, etc.
First time I ran it? It worked! Kinda subtle stuff, threads, in new interlocking behavior, and it works, first try. I'm liking Rust.
I think I understand why you don't care about spurious wakeups but I wanted to ask one more thing, just to complete my understanding and in case it is not clear to other readers.
You do a check of some kind on every wakeup that examines some sort of state, and that state doesn't need to be explicitly protected by the mutex because it is protected by some other Sync data structure, or at least in an UnsafeCell (and only accessed with the mutex held) so it is guaranteed to be read from memory.
Is that correct?
I have one thread producing data and one or more threads "subscribing" to it, let's say.
I already had a polling call that looks for data, and it looks in a mutex-protected circular buffer to find the data.
What I added was a blocking version of my polling call, but with a timeout, so I used a
Condvar to wake all the sleeping threads that are interested in the circular buffer. They each need to look and see whether they are interested in the new data, and the new data might be consumed by the time some get a chance to look—and that normal case of look-but-find-nothing is quite like a spurious wake up.
Thanks, that makes perfect sense. And glad to hear you're having a good time with Rust!
Did you mean
tokio::sync::Semaphore? I don't see one in
No, I did mean
std::sync::Semaphore, but not with too much affection nor even that much specificity; I saw various things when I searched for "rust semaphore", and as I breezed through them looking for a parameter that looked like a timeout, it seemed none of them did what I wanted. Which is why, when I landed on using
Condvar in a degenerate way, I asked whether it was the right thing to use.
Looking again now I do see a
std::sync::Semaphore, but it looks like it dates from nightly from the beginning of time.
I suspect need to have a better search strategy when trolling for new Rust stuff than just typing into duckduckgo.com "rust" followed by a few more words and getting both current stuff and very obsolete stuff from, say, Brandeis University and the beginning of time. But I don't just want hits from crates.io or lib.rs, I don't just want things from The Book and its cousins. I also want stuff from stackoverflow.com, and even Medium posts where I can only see the first paragraph. Maybe just being smarter about parsing what I see will do it.
-kb, the Kent who is getting smarter and quickly.