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: sync: add RWMutex.DowngradeLock #23513
Comments
What are the practical uses of this feature along with the benchmarks compared to the existing implementation as well as atomic load/copy/swap? |
A practical usage example is given in the proposal. The cost of DowngradeLock() is strictly less than a "Unlock(); RLock()" Benchmark:
Result:
|
We can protect the consistency from panic by "Lock(); defer Unlock(); doPanicThing()". Is there a way to do so when it comes to …
|
I'm not convinced this is helpful in a real program, and there is a real cost to adding complexity to the API. Please show us benchmarks improving a real workload, not a microbenchmark. |
To use defer, one would have to introduce a variable to track the lock state:
But I think using @rsc: I do have benchmarks that show a measurable improvement in a critical hot path of my application, but I can't share them publicly. I've contacted you privately. |
Sounds like a major disadvantage, it would be another shiny feature that's easy to misuse. Without an actual benchmark, it's not easy to see the advantage. If a clear example isn't trivial to write, maybe that's a further argument for the feature's unwarranted complexity. |
Note that you can substitute a custom RWMutex implementation into your own code (copy and modify). We don't want to add the complexity here - and support it forever - especially with such an awkward API. |
The proposed
sync.RWMutex.DowngradeLock
atomically downgrades from a write(or "exclusive") lock to a read (or "shared") lock. A typical pattern in which
it is useful is:
Without
DowngradeLock
, this must instead be:This latter form allows
val
to be concurrently invalidated betweenrw.Unlock()
andrw.RLock()
at (2), with the following consequences:If
cache.Fill()
can returnval
, as in (1),DowngradeLock
's atomicityallows
foo
to be passed directly todoExpensiveThing()
. This is notpossible without
DowngradeLock
, necessitating a subsequent call tocache.Get(key)
which may be expensive.Needing to loop to handle invalidation makes the cost of the latter form
unbounded, and may result in livelock if concurrent calls to
cache.Fill(key)
compete for a limited resource such as cache capacity.The text was updated successfully, but these errors were encountered: