Are recursive locks needed?

Are recursive locks needed?

Has anyone needed to use recursive locks in a threaded application? If so, in what kind of application? Would some other synchronization or mutual exclusion scheme also worked, but have been more complicated to implement or maintain?

--clay

4 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Clay,

There is some ambiguity in the term "recursive lock". I am not quite sure what you meant by this. From within the thread that currently owns the lock, and depending on the design of the codeto which the lock protects, relocking may be safe or it may be unsafe. If unsafe then the thread is at deadlock (or at risk of running afoul). If safe then the owning thread can maintain a counter for the nesting level. If the thread local counter is 0 then it knows it does not own the lock and it attempts to lock the resource. On successfull lock it can incriment the thread local lock count. If the thread local counter were not 0 then it can incriment the thread local lock count. On release it can decriment the count and only when count reaches 0 does the thread formaly unlock the resouce.

Granted, you may want to hide this from routines of an application by making the recursiveness (to the owner)an attribute of the lock handle.

I've found them to be useful in some cases, but certainly not necessary. That said, here's a recent example--garbage collection code for the D programming language (support code for a typical lock all threads, mark/scan method):


void lockAllThreads() {
ScopedLock sl( A );
foreach( Thread t; allThreads )
t.suspend();
}

class Thread {
// public to allow its use in debugging and such
void suspend() {
ScopedLock sl( A );
if( suspendCount++ < 1 )
// suspend thread
}
}

It's obviously far more efficient (and safe) to acquire a single lock for lockAllThreads than to lock the list and then lock each call to suspend separately, and recursive locks make such an implementation quite simple.

Sean -

This is something like what I had in mind. My scenario had a lock associated with some specific data and several functions that access that data. Each woulduse the samelock to protect access. However, if some function could call one or more of the others, recursive locks would make this very easy to implement.

For example, functions A, B, and C all access the shared data and can be called individually. Also, A can call B from within the critical region, and B can call C from that critical region. I suppose having three locks that must be acquired at each function would solve the problem, but this seems overkill for the times when each function may be called individually. Adding more functions to the chain or having some recursions (e.g., C can call A from the critical region), quickly breaks the multiple lock solution.

--clay

Leave a Comment

Please sign in to add a comment. Not a member? Join today