red floyd <no.s...@here.dude> writes: >Does POSIX define what happens when a pthread currently holding a mutex >locks the same mutex? >i.e. >void f() >{ > pthread_mutex_lock(&some_mutex); > pthread_mutex_lock(&some_mutex); >} >The Linux (MDK9.1) implementation of pthreads has a non-portable mutex >attribute letting you specify what behavior you want in said situation. >I'd like to try to write portable code, though.
Casper -- Expressed in this posting are my opinions. They are in no way related to opinions held by my employer, Sun Microsystems. Statements on Sun products included here are not gospel and may be fiction rather than truth.
OK, thanks Joe and Casper. I guess my systems implementation is older, and thus the recursive mutex hadn't yet been standardized or something. So I'll simply #define something like this
1) You don't know the mutex is being used recursively. In this case, the recursive mutex will hide a serious problem.
2) You know the mutex is being recursively. In this case, just don't lock it since you know it's already locked anyway.
The problem is that recursive mutexes hide something from you and that something is extremely important. Consider code like this:
A) Lock mutex B) Unlock mutex C) Do something, assuming the mutex is unlocked
What happens if the mutex is recursive?
The only value of a recursive mutex is that it allows you to write a function that works properly whether or not a mutex is locked. But the caller must know that the mutex is locked anyway, so why not just have two versions of the function? (With the one you call without a lock possibly just being a wrapper that grabs the lock and calls the other function.)
It's just too hard and dangerous to write sensible code that works with a mutex that might or might not start out with that mutex locked and with no way to tell which. And the only value of recursive mutexes is that they let you do this.
> It's just too hard and dangerous to write sensible code that works with > a mutex that might or might not start out with that mutex locked and with no > way to tell which. And the only value of recursive mutexes is that they let > you do this.
SenderX wrote: >> It's just too hard and dangerous to write sensible code that >> works with a mutex that might or might not start out with that mutex >> locked and with no way to tell which. And the only value of >> recursive mutexes is that they let you do this. > There good for hashed locks.
I can't imagine how. The only way they might help is if you have code that grabs more than one object and they might 'happen to' have the same lock protecting them. But if your code does this, they might also happen to have different locks protecting them. In this case, you must enforce your lock ordering rules or else you can deadlock.
In other words, if one thread can grab object A then object B, grabbing lock 1 followed by lock 2, another thread could grab object C followed by object D, grabbing lock 2 followed by lock 1. Then you deadlock.
So if you're going to use hashed locks, you may either hold two locks at once or you may not. If you may not, recursive locks don't help.
If you may, then you must check to see what locks they refer to so that you acquire them in the right order. While you're doing this, it's just as easy to check if they're the same lock, and if so only acquire it once. So recursive locks don't help you in this case.
Worse, recursive locks might lull you into thinking you don't have to check what locks you are acquiring, and then you are vulnerable to lock order reversal and deadlocks.
red floyd wrote: > Alexander Terekhov wrote: >> red floyd wrote: ...
>> Don't use recursive mutexes. It's akin to sex with used condoms. ;-)
>> regards, >> alexander.
> May I ask why?
Other than Mr. Schwartz reply (which I consider absolutely good), I may add also that recursive mutexes are slower (they must check if they are locked or not) and brings you to program less carefully about shared resource usage. If you stop to think twice about that, you'll realize that when you want to lock a resource, you just want to know that you are the owner of that, and not that you've been entitled to be the owner N times...
The only reason I can see for recursive mutexes is to call recursive functions, where the locks are so complex that writing a wrapper is not a viable way, or to create "onion peel" like libraries where the lower levels are completely obscure and abstracted to the higher ones, and there is sometimes the need to "extend" the mutex locking also to some function in the higher levels; but in both the cases there are probably better ways to deal with the problem with a non recursive mutex, with a little more cleaner design effort.