Subj : Re: Recursive lock? To : comp.programming.threads From : David Butenhof Date : Thu May 19 2005 01:22 pm axter wrote: > What exactly is meant by recursive lock, and is it bad, and if so why? You got it right below, so I'll follow up with the "bad and why" at the end. > Also, does the POSIX standard support recursive lock via > pthread_mutex_lock? Yes; you use the same functions, after initialization with an attributes object specifying the recursive mutex type. Beware; although you can use a recursive mutex for pthread_cond_wait(), this will only UNLOCK, not necessarily RELEASE the mutex. (That is, if your thread holds the lock at a "depth" greater than 1, you've only decreased the counter by one.) This is good, because holding a lot implies that you have unstable data predicates being protected by the lock. (Otherwise you would have UNLOCKED so that other threads can make concurrent progress on the shared data.) > In another thread, someone stated that a code requirement was bad > because it required recursive lock, so I'm trying to understand his/her > position. > > I believe recursive lock means you can call the lock multiple times > from the same thread and it won't block your thread. > I'm not sure if it means you need to call unlock the same amount of > times you called lock. Yes, because the idea is that each of the recursive lock regions is independent. If they KNEW about each other, you wouldn't need a recursive mutex because you could keep track yourself more efficiently. So as long as any of your code still has unstable shared data predicates, the lock must remain held by the thread. Only when ALL lock regions have announced their predicates are stable (by unlocking) can the lock be RELEASED to allow access by other threads. This is the evil of recursive mutexes. They sound convenient and "safe". But concurrency is the "bread and butter", the "raison d'etre" of threading. The longer you hold a mutex (also known as "bottleneck"), the more you restrict (or prevent) concurrency. If your predicates are stable, you should unlock. If you're locking mutexes recursively, you're saying that you don't know (or don't care) whether your predicates are stable. You're not understanding, or managing, your concurrency. And that means you're not writing a clean and efficient threaded program. This is not to say that all threaded programs need to be "clean and efficient". Sometimes people use threads simply as a program structuring device -- a way to separate call stacks, just a portable way to write co-routines. In that case (like our recently prolific contributer Uenal Mutlu), you may not care about concurrency, or even performance. It'll cost you many wasted context switches (especially if your threads are timesliced, because timeslices will frequently happen while your thread is holding a lock, and other threads will just need to block until the owner runs again to complete and unlock). This seems to me a bit like using a coffee mug to pound nails, but it's your mug and your nails; and if that's what makes you happy it's OK by me. ;-) -- Dave Butenhof, David.Butenhof@hp.com HP Utility Pricing software, POSIX thread consultant Manageability Solutions Lab (MSL), Hewlett-Packard Company 110 Spit Brook Road, ZK2/3-Q18, Nashua, NH 03062 .