#include <stdio.h>
#include <errno.h>
#include <pthread.h>
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
void *func(void *arg)
{
while (1) {
printf("begin\n");
pthread_rwlock_wrlock(&rwlock);
printf("fall through wrlock\n");
pthread_rwlock_wrlock(&rwlock);
printf("fall through wrlock\n");
pthread_rwlock_unlock(&rwlock);
printf("fall through unlock\n");
pthread_rwlock_unlock(&rwlock);
printf("end\n");
}
}
int main()
{
pthread_t thd;
pthread_create(&thd, NULL, func, NULL);
sleep(100);
}
~
I write code above on UBUNTU 10.04 and run,
It just output
root@ubuntu:~# ./a.out
begin
fall through wrlock
fall through wrlock
fall through unlock
end
begin
..and finally block here
Why it does not block when the first time
the second
pthread_rwlock_wrlock(&rwlock)
called
This is from the Open Group page on
pthread_rwlock_wrlock.What you’re doing is undefined, at least in that version of the spec. You’re lucky that vicious monkeys didn’t fly in through the window and beat you to death 🙂
In any case, you really should be checking the return code from all your pthread functions. They can fail, and you really don’t want to continue on the assumption you have a lock when in fact you don’t, since that sort of negates the usefulness of locks.
That same page linked to above states:
I’d be checking to see if you’re actually getting back the
EDEADLKerror code. This error code is a possibility even in the latest editions of POSIX threads where, as Nemo points out in a comment, the “undefined” wording has been removed.One thing is still a worry however. The latest spec states that the “calling thread may deadlock if at the time the call is made it holds the read-write lock” (my bold).
I see this as an actual deadlock, ie, the thread totally locks up. The
EDEADLKerror code section also states that the “pthread_rwlock_wrlock()function may fail if …” (again, my bold).Both those statements have the weasel word “may” in them, so it’s still not clearly defined which will happen in any given situation. It may (no pun intended) be that this was left unspecified because certain implementations behaved differently (it’s not always easy to detect a deadlock situation in advance) although that’s pure speculation on my part.
Bottom line, unless you know you have a recursive lock of some sort (where you can relock with impunity), don’t do it.