(一)当前被读锁占着
1。如果读优先(默认是PTHREAD_RWLOCK_PREFER_READER_NP,即读优先),那么等着的读请求可以快速拿到锁,写一直被饿着(直到没有任何等待获取读锁的情况下,写才能拿到写锁);
2。如果写优先,那么读和写都等着,一但前面的读释放了锁,写立刻就会优先读来拿到锁;
(二)当前被写锁占着
不论谁优先,都需要把所有等着的写都服务完,才会给读机会,所以写多读少的情况下,就应该用互斥锁了;
测试程序:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <stdint.h>
#include <pthread.h>
#include <vector>
#include <map>
#include <set>
using namespace std;
long g_idx = 0;
class ThreadRwLock {
private:
pthread_rwlock_t m_rw_mutex;
public:
ThreadRwLock() {
pthread_rwlockattr_t attr;
// 设置写优先
pthread_rwlockattr_init(&attr);
//pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
pthread_rwlock_init(&m_rw_mutex, &attr);
}
~ThreadRwLock() {
pthread_rwlock_destroy(&m_rw_mutex);
}
void rdlock() {
pthread_rwlock_rdlock(&m_rw_mutex);
}
void wrlock() {
pthread_rwlock_wrlock(&m_rw_mutex);
}
int tryrdlock() {
return pthread_rwlock_tryrdlock(&m_rw_mutex);
}
int trywrlock() {
return pthread_rwlock_trywrlock(&m_rw_mutex);
}
void unlock() {
pthread_rwlock_unlock(&m_rw_mutex);
}
};
ThreadRwLock g_lock;
void* thread_routine(void* arg) {
long is_write = (long)arg;
if (is_write) {
printf("%lu wait write lock\n", pthread_self()); fflush(stdout);
g_lock.wrlock();
long idx = __sync_add_and_fetch(&g_idx, 1);
printf("%lu get write lock, %ld\n", pthread_self(), idx); fflush(stdout);
sleep(5);
g_lock.unlock();
} else {
printf("%lu wait read lock\n", pthread_self()); fflush(stdout);
g_lock.rdlock();
long idx = __sync_add_and_fetch(&g_idx, 1);
printf("%lu get read lock, %ld\n", pthread_self(), idx); fflush(stdout);
sleep(5);
g_lock.unlock();
}
return NULL;
}
int main(int argc, char* argv[]) {
pthread_t tid = 0;
pthread_create(&tid, NULL, thread_routine, (void*)0);
pthread_create(&tid, NULL, thread_routine, (void*)0);
pthread_create(&tid, NULL, thread_routine, (void*)0);
pthread_create(&tid, NULL, thread_routine, (void*)0);
pthread_create(&tid, NULL, thread_routine, (void*)0);
pthread_create(&tid, NULL, thread_routine, (void*)1);
getchar(); //让程序暂停,等待键盘敲入一个字节后,接着走
pthread_create(&tid, NULL, thread_routine, (void*)1);
sleep(2); //确保写锁被优先拿到
pthread_create(&tid, NULL, thread_routine, (void*)0);
pthread_create(&tid, NULL, thread_routine, (void*)0);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)0);
pthread_create(&tid, NULL, thread_routine, (void*)0);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)1);
pthread_create(&tid, NULL, thread_routine, (void*)0);
pthread_create(&tid, NULL, thread_routine, (void*)0);
getchar();
return 0;
}