读写锁优先级的问题解决了

这个问题就是:对于一个共享的数据结构,读的频率远远大于写,所以用了读写锁.但是发现写线程总是抢不到锁.

按The Open Group 的Single UNIX Specification所说,"The pthread_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
};

/* Set reader/write preference.  */
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的一个成员变量。那是为啥呢?

再google,终于找到了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 呢。

OK!问题解决。

此博客中的热门博文

少写代码,多读别人写的代码

在windows下使用llvm+clang

tensorflow distributed runtime初窥