Subj : Re: Recursive lock? To : comp.programming.threads From : doug Date : Thu May 19 2005 07:07 pm "David Butenhof" wrote in message news:xy%ie.5692$p76.2269@news.cpqcorp.net... > 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. This is the part Uenal doesn't get. (He also doesn't understand that recursive locks need synchronisation between threads on SMP systems, even the case where you already own the lock (because you have to find out). [Actually, you can use TLS for this, but then you make the fast-path slower, so what's the point?]) > > 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 .