这个问题就是:对一个同享的数据布局,读的频率远弘远于写,所以用了读写锁.但是发现写线程老是抢不到锁.
按The Open Group 的Single UNIX? Specification所说,"Thepthread_rwlock_rdlock() function applies a read lock to the read-write lock referenced by rwlock. The calling thread acquires the read lock if a writer does not hold the lock and there are no writers blocked on the lock. It is unspecified whether the calling thread acquires the lock when a writer does not hold the lock and there are writers waiting for the lock" 意思就是说,没有writer在等写锁的时辰,reader是可以拿到读锁的。然则没有划定,若是有writer在期待写锁,该若何?
还好,Linux有pthread_rwlockattr_setkind_np这个函数,惋惜我用man查不到这个函数。我是在pthread.h头文件中发现的。
enum
{
PTHREAD_RWLOCK_PREFER_READER_NP,
PTHREAD_RWLOCK_PREFER_WRITER_NP,
PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,
PTHREAD_RWLOCK_DEFAULT_NP = PTHREAD_RWLOCK_PREFER_READER_NP
};
?
extern int pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *__attr,
int __pref) __THROW __nonnull ((1));
看到这些,我觉得这事不就这么简单的就解决了吗?默许是reader优先,改成writer优先不就好了吗?唰唰唰的写代码,同时在网上搜了一下,csdn上还有人很当真的教他人怎样用这个函数。啧啧!
pthread_rwlockattr_setkind_np(&attr,PTHREAD_RWLOCK_PREFER_WRITER_NP);
没用!为啥呢?连man页都没有,所以我思疑这个函数没实现,因而就用debuginfo-install glibc? 装glibc的调试符号,然后用gdb跟进去,发现pthread_rwlockattr_setkind_np确切是有实现的,代码很简单,更改了attr的一个成员变量。那是为啥呢?
再谷歌,终究找到了pthread_rwlockattr_setkind_np的man page,末尾有一段notes,让我年夜汗:
“Setting the value read-write lock kind to PTHREAD_RWLOCK_PREFER_WRITER_NP, results in the same behavior as setting the value to PTHREAD_RWLOCK_PREFER_READER_NP. As long as a reader thread holds the lock the thread holding a write lock will be starved. Setting the kind value to PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, allows the writer to run. However, the writer may not be recursive as is implied by the name. “
意思就是说,PTHREAD_RWLOCK_PREFER_WRITER_NP和PTHREAD_RWLOCK_PREFER_WRITER_NP是一样滴!应当设置成PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP才对!可是PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP也是名存实亡滴,它才不会recursive 呢。