New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: x/sync: create CondMutex, inspired by Abseil #41354
Comments
LockWhen should likely be a helper function, not a method on the type. |
Do you have any supporting evidence that sync.Cond is widely used? Does that data support your concern that it sync.Cond is widely misused or error prone? |
see #21165 for earlier discussion on |
There is rarely a reason to use condition variables in Go. I doubt many programs would benefit from this. It seems to me that using callbacks trades one kind of error-prone construction for a different kind. Bad things will happen if the callback does anything with the |
The doc comment seems to be wrong. The "equivalent" Go code says that Await starts by locking the mutex, while the text says that the caller must already hold the mutex. If both were true, Await would be guaranteed to deadlock. Is there a reason this kind of abstraction cannot be developed in a third-party package first? |
@davecheney, my experience supports the assessment that The section of my concurrency talk on condition variables starts at slide 37. In the talk, I enumerated four specific problems with condition variables: spurious wakeups, forgotten signals, starvation, and unresponsive cancellation. As far as I can tell, this proposal would address, at best, half of those: forgotten signals and unresponsive cancellation. (@riking suggests that it would also address spurious wakeups, but I don't think that's strictly true: the call to I would rather we encourage Go users to learn and apply appropriate channel-based alternatives. |
@bcmills thanks, for the record, I’m not in favor of this proposal. |
Thanks for the additional perspective! |
Overview
Create a new type,
sync.CondMutex
, which extends Mutex with some additional methods that allow it to also act as a condition variable.Background
Abseil's Mutex provides an implicit condition variable integrated into the standard Mutex, as documented here: https://abseil.io/docs/cpp/guides/synchronization#conditional-mutex-behavior
The documentation at that link explains more details of this API.
Goals
Because the CondMutex internally takes care of bookkeeping and calling Signal(), it can eliminate many of the error-prone constructions that arise when writing code using condition variables. Users would no longer need to write the while loop themselves, and the mutex can internally take care of selecting the correct waiter (if any) by checking the condition they are waiting on, eliminating or reducing spurious wakeups.
If this API were available, it would completely eliminate manual usage of
sync.Cond
from at least two of my programs that I can think of right now.Unresolved Issues
Functions cannot be compared for equality, so outside of reflection or runtime trickery there is no available mechanism for coalescing identical conditions.
Making the condition a field of the mutex (only allowing one possible condition), and allowing calling code to choose whether to use the condition or not, would solve this issue (allowing good performance benefits) at the cost of only allowing one possible condition, as well as potentially introducing brand-new synchronization pathologies to the ecosystem.
The text was updated successfully, but these errors were encountered: