When Recursive Locks Are Good
This old post by David Butenhof somehow floated to the top of the reddit ether today. It is a great read, and he makes some very strong points, but I think he’s looking at it too much from a systems perspective, and missing the key advantage of recursive locks that matters for application development: encapsulation.
Now, to say he missed encapsulation is not entirely fair. He clearly is aware of the concept, but feels you should never hold on to a lock long enough for encapsulation to matter. I hear what he’s saying, but crossing encapsulation boundaries doesn’t necessarily mean you are spending that much time holding on to a lock. It just means that the lock is being used by two disparate systems that really shouldn’t have to know about each other.
Here’s a simple case that I’ve seen come up: you have some kind of transactional persistent store (read: a database). Your application updates said persistent store fairly regularly. During those updates, it often needs to acquire locks because certain bits of the persistent store aren’t reentrant (say the local write-back cache). Fortunately the system is cleverly designed so that in the 90% case the non-reentrant code isn’t touched, so you still get a high level of concurrency. You app, being the good app that it is, also has a generic logging framework. It supports all kinds of different logging levels and targets, and has this wonderful efficient and reentrant interface where it only chews up 4 CPU cycles in the event that a log is disabled. It’s so great that you even log directly from your transactions with all the transactional context making it to the log. All is great right?
Now what if you configure the logging system to have the transactional persistent store as a logging target? ;-)
The problem is that your logging framework shouldn’t have to care whether you already have a lock on the persistent store. Now, Mr. Butenhof’s argument is that you shouldn’t do the logging until you are done with the lock, but there is important information in the context of the transaction that would be lost once the lock was released. You could copy the information, but you’d be copying data while holding the lock for a logging event that may very well be disabled, and even if it was enabled, the probabilities that both the application and the logging framework need the lock are so low, that this actually increases the average length of time locks are held, thereby increasing contention, not to mention adding overhead in general. The best part is that to even know that this work might necessary you have to look at the config file.
Now, you could make the lock manage all this for you, but ultimately it boils down to you implementing the recursive lock yourself, and probably in a much less efficient way. In short, as with all things, it’s hard to make sweeping categorical statements, and this is why API designers typically have to provide more flexibility than they want to.
Specific contexts where recursive locks are helpful:
- the probability that the lock will be used recursively is small (say you have to lock two records in a table that has page-level locking)
- the lock explicitly exists as a trade off between concurrency and resources like CPU, memory and IO (caching for example).
- the lock protects a common resource that is shared by two highly disparate systems (see above)
Not surprisingly, there tends to be a lot of overlap between those cases.
I would say that in general, recursive locks should not be your first choice, as all the drawbacks mentioned in that post do exist. That said, understanding those drawbacks, and knowing when and how to use recursive locks is key for implementing concurrent systems.
Trackbacks
Use the following link to trackback from your own site:
http://xblog.xman.org/trackbacks?article_id=when-recursive-locks-are-good&day=25&month=09&year=2006
-
Christopher Smith has tried very hard to come up with a case where a recursive lock is a good thing ™. And while the article is very well thought out and presented, apparently David Butenhof (the creator of my favorite book on POSIX Threads)...
-
Wow, my first experience with a trackback-based thread! I’m such a blogging newbie that this seems like a big deal to me. Michael Suess has examined my article on why recursive threads are sometimes good and has come up with some excellent q...