对于pthread_rwlock_t读写锁:
一个线程持有着写锁,又去加(该锁的)读锁,可能会产生死锁。
一个线程持有着(读或者写)锁,又去加(该锁的)写锁,可能会产生死锁。
此时pthread_rwlock_rdlock和pthread_rwlock_wrlock会返回EDEADLK,加锁失败。
pthread_rwlock_rdlock:If a writer holds the lock, the calling thread shall not acquire the read lock. The calling thread may deadlock if at the time the call is made it holds a write lock.
pthread_rwlock_wrlock:The calling thread may deadlock if at the time the call is made it holds the read-write lock (whether a read or write lock).
另外pthread_rwlock_rdlock还可能返回EAGAIN,意为读锁已达上限。除此之外,两个函数不会返回其他错误了。
如果不检查pthread_rwlock_rdlock和pthread_rwlock_wrlock的返回值,就认为返回后就拿到了锁,会产生未定义后果,比如:
printf("EDEADLK is %d\n", EDEADLK);
printf("EAGAIN is %d\n", EAGAIN);
int ret = 0;
pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER;
ret = pthread_rwlock_wrlock(&lock);
printf("wrlock return value is %d\n", ret);
ret = pthread_rwlock_rdlock(&lock); //加锁失败!
printf("rdlock return value is %d\n", ret);
pthread_rwlock_unlock(&lock);
pthread_rwlock_unlock(&lock); //本线程未加锁却解锁会产生未定义后果
ret = pthread_rwlock_rdlock(&lock);
printf("rdlock return value is %d\n", ret);
pthread_rwlock_unlock(&lock);
这段代码看着可能很傻,但如果将写锁和读锁放到两个函数里,一个函数调用另一个函数,就比较容易发生了。
所以加锁的时候要判断下返回值,如果是EDEADLK,可以直接终止程序。