(一)當前被讀鎖占著
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;
}