在多線程程式中,有一種讀寫者的問題,即對某些資源的通路,存在兩種可能的情況,一種是通路必須排他的,稱為寫操作;另外一種通路是可共享的,稱為讀操作。
處理讀寫着問題的兩種常見政策是:強讀者同步和強寫者同步。在強讀者同步過程中,總是給讀者優先權,隻要寫着目前沒有進行寫操作,讀者就可以獲得通路權。在強寫者同步過程中,通常将優先權先交給寫者,而将讀者延遲到所有等待的或者活動的寫者都完成為止。簡單的說:
(1)可以同時存在多個讀操作
(2)寫必須互斥(隻允許一個寫操作,不能讀寫操作同時進行)
(3)寫操作優先于讀操作,(一旦有寫操作,後續的讀操作必須等待,喚醒時有限考慮寫操作)
下面是兩種讀寫鎖的使用示例.
一:POSIX 下的rw_lock
點選(此處)折疊或打開
#include pthread.h>
#include cstdlib>
#include ctime>
#include iostream>
using namespace std;
static int count = 0;
class Test
{
private :
pthread_rwlock_t rwlock;
static void* shared_task_handler(void* arg)
{
Test* testptr = static_castTest*>(arg);
pthread_rwlock_rdlock(&testptr->rwlock);
// do the shared task here
cout "read---count = " count endl;
if (pthread_rwlock_unlock(&testptr->rwlock) )
{
cout "read unlock error " endl;
}
return NULL;
}
static void * exclusive_task_handler(void * arg)
pthread_rwlock_wrlock(&testptr->rwlock);
//do the exclusive task here
++count;
cout "write--count = " count endl;
cout "write unlock error " endl;
public :
typedef void* (*ThreadFunc) (void*);
void start()
srand(time(NULL));
if( pthread_rwlock_init(&rwlock,NULL) )
cout "rwlock init error " endl;
const int THREADS_NO = rand()%100;
pthread_t* threads = new pthread_t[THREADS_NO];
for(int i = 0; i THREADS_NO; ++i)
ThreadFunc tmpfunc = rand() % 2 ? shared_task_handler : exclusive_task_handler;
if (pthread_create(threads+i,NULL,tmpfunc,this))
{
cerr "pthread_create fails" endl;
exit(1);
}
rwlock
for(int i=0; iTHREADS_NO; i++)
pthread_join(threads[i],NULL);
delete[] threads;
};
int main()
Test tmptest;
tmptest.start();
}
output:
lee@lee-desktop:~/share$ ./posix_read_write_lock
write--count = 1
write--count = 2
write--count = 3
read---count = 3
write--count = 4
read---count = 4
write--count = 5
write--count = 6
read---count = 6
write--count = 7
write--count = 8
read---count = 8
write--count = 9
write--count = 10
read---count = 10
write--count = 11
write--count = 12
write--count = 13
write--count = 14
write--count = 15
read---count = 15
二:利用pthread_cond_* & pthread_mutex_* 實作rw_lock
class RWLock
pthread_mutex_t cnt_mutex;
pthread_cond_t rw_cond;
int rd_cnt, wr_cnt;
RWLock(const RWLock&);
RWLock& operator= (const RWLock&);
RWLock(): rd_cnt(0),wr_cnt(0)
pthread_mutex_init(&cnt_mutex, NULL);
pthread_cond_init(&rw_cond, NULL);
void get_shared_lock()
pthread_mutex_lock(&cnt_mutex);
while (wr_cnt >0)
pthread_cond_wait(&rw_cond,&cnt_mutex);
rd_cnt++;
pthread_mutex_unlock(&cnt_mutex);
void release_shared_lock()
rd_cnt--;
if (0 == rd_cnt)
pthread_cond_signal(&rw_cond);
void get_exclusive_lock()
while (rd_cnt + wr_cnt>0)
wr_cnt++;
void release_exclusive_lock()
wr_cnt--;
pthread_cond_broadcast(&rw_cond);
~RWLock()
pthread_mutex_destroy(&cnt_mutex);
pthread_cond_destroy(&rw_cond);
RWLock lock;
testptr->lock.get_shared_lock();
testptr->lock.release_shared_lock();
testptr->lock.get_exclusive_lock();
testptr->lock.release_exclusive_lock();
output:
lee@lee-desktop:~/share$ ./read_write_lock
read---count = 0
read---count = 1
read---count = 11
read---count = 13
write--count = 16
write--count = 17
write--count = 18
write--count = 19
read---count = 19
write--count = 20
read---count = 20
write--count = 21
read---count = 21
write--count = 22
read---count = 22
write--count = 23
read---count = 23
write--count = 24
read---count = 24
write--count = 25
write--count = 26
write--count = 27
write--count = 28
read---count = 28
write--count = 29
write--count = 30
read---count = 30
write--count = 31
read---count = 31
write--count = 32
read---count = 32
write--count = 33
read---count = 33
write--count = 34
write--count = 35
參考:
http://www.cppblog.com/bigsml/archive/2006/09/07/12137.html