5 ms·
The rule of thumb for multiple locks is always acquire them in the same order. Lock A, lock B, unlock B, unlock A. Otherwise you risk a deadlock. If another thr
by ntoskrnl 4y ago
The rule of thumb for multiple locks is always acquire them in the same order. Lock A, lock B, unlock B, unlock A. Otherwise you risk a deadlock. If another thread locks B, then tries to lock A, you're in trouble.
- mandevil 4y agoAnd keeping that discipline over many developers, over many years, is in practice impossible, which is why multiple locks seem attractive but are actually a major problem for complex systems.
- layer8 4y agoYou can, of course, encapsulate such a lock order with dedicated classes (or functions/closures) modeling linear types enforcing the sequence of lock A > lock B > unlock B > unlock A. The resulting objects can still be misapplied, but should fail immediately with a runtime error, making it much harder to inadvertently misuse.
- jerf 4y agoBut that still doesn't scale up to more locks of that size very well, because you start trying to take even more of them, and in dynamic orders, and etc etc. I know about the theoretical solution of taking locks always in a defined order, but I don't consider it a practical solution. If taking locks willy-nilly lets you scale to program size X, this might give you 2X or 3X, but that's not nearly large enough in practice. & dandelany, the community has chipped in and answered for me. I endorse this subthread, at least, as I write this comment. :)
- dandelany 4y agolove when that happens :) Thanks!
- anarazel 4y agoIME there's plenty problems where nested locks will lead to a simpler solution than trying to avoid them. It's important to avoid when reasonably doable, but it's also not uncommon to take it too far and end up with a slower and way more complicated solution.
- mandevil 4y agoThe problem here is when you have more than 2, and especially as it combinatorially expands as you get more and more locks. Now I need Lock A, Lock C, and Lock F, but then this other critical section needs Lock A, Lock D, and Lock F, and if you are encapsulating then you start needing a whole lot of different functions for all the different combinations, and have to make sure that all are consistent. I've got multi threaded C++ in production right now, and it is because the code is small and avoids multiple locks that I have any faith in it. As a code base expands, in kloc and in time, this gets harder and harder to reason about.
- astrange 4y agoYou can break this on a live system if you're in a debugger and manually lock one of the inner locks. danluu claims there's other reasons it's not good enough but I was never able to figure out what he meant. Exception safety maybe.