- 论坛徽章:
- 0
|
/* g++ -Wall -o rwlock rwlock.cpp -lpthread
*
* 一个写优先读写锁的实现,多线程频繁读,多线程少量写,同时写优先,性能极佳。
* 当写锁(独占锁)lock成功的必要条件是:
* 1. 将写锁计数++;
* 2. 会阻塞后续对读锁(共享锁)的读;
* 3. 等待读锁的计数为0;
* 4. 等待写锁的计数为1;
*
*/
#include pthread.h>
#include cstdlib>
#include ctime>
#include iostream>
#include time.h>
using namespace std;
class RWLock
{
private :
pthread_mutex_t cnt_mutex;
pthread_cond_t rw_cond;
int rd_cnt, wr_cnt;
RWLock(const RWLock&);
RWLock& operator= (const RWLock&);
public :
RWLock(): rd_cnt(0),wr_cnt(0)
{
pthread_mutex_init(&cnt_mutex, NULL);
pthread_cond_init(&rw_cond, NULL);
}
void get_shared_lock()
{
pthread_t tag = pthread_self();
pthread_mutex_lock(&cnt_mutex);
rd_cnt++;
time_t now = time(NULL);
printf("[%lu]r_lock[thread_0x%x] r=%d w=%d\n", now, (int)tag, rd_cnt, wr_cnt);
while (wr_cnt >0)
{
printf("\t\t r_lock wait for wr_cnt[%d]\n", wr_cnt);
pthread_cond_wait(&rw_cond,&cnt_mutex);
}
pthread_mutex_unlock(&cnt_mutex);
}
void release_shared_lock()
{
pthread_t tag = pthread_self();
pthread_mutex_lock(&cnt_mutex);
rd_cnt--;
time_t now = time(NULL);
printf("[%lu]r_unlock[thread_0x%x] r=%d w=%d\n", now, (int)tag, rd_cnt, wr_cnt);
if (0 == rd_cnt)
{
printf("\t\t r_unlock[thread_0x%x] rd_cnt=0, so singal to wr_cnt[%d]\n", (int)tag, wr_cnt);
pthread_cond_signal(&rw_cond);
}
pthread_mutex_unlock(&cnt_mutex);
}
void get_exclusive_lock()
{
pthread_t tag = pthread_self();
pthread_mutex_lock(&cnt_mutex);
wr_cnt++;
time_t now = time(NULL);
printf("=====[%lu]w_lock[thread_0x%x] r=%d w=%d\n", now, (int)tag, rd_cnt, wr_cnt);
while (rd_cnt+wr_cnt>=2)
{
printf("\t\t w_lock wait r=%d w=%d\n", rd_cnt, wr_cnt);
pthread_cond_wait(&rw_cond,&cnt_mutex);
}
printf("=====\t\t w_lock[thread_0x%x] get ok r=%d w=%d\n", (int)tag, rd_cnt, wr_cnt);
pthread_mutex_unlock(&cnt_mutex);
}
void release_exclusive_lock()
{
pthread_t tag = pthread_self();
pthread_mutex_lock(&cnt_mutex);
wr_cnt--;
time_t now = time(NULL);
printf("=====[%lu]w_unlock[thread_0x%x] r=%d w=%d, then broadcast\n", now, (int)tag, rd_cnt, wr_cnt);
pthread_cond_broadcast(&rw_cond);
pthread_mutex_unlock(&cnt_mutex);
}
~RWLock()
{
pthread_mutex_destroy(&cnt_mutex);
pthread_cond_destroy(&rw_cond);
}
};
static RWLock lock;
class Test
{
private :
static void* shared_task_handler(void*)
{
while(1)
{
sleep(1);
lock.get_shared_lock();
sleep(1);
lock.release_shared_lock();
}
return NULL;
}
static void * exclusive_task_handler(void*)
{
while(1)
{
sleep(3);
lock.get_exclusive_lock();
sleep(1);
lock.release_exclusive_lock();
}
return NULL;
}
public :
typedef void* (*ThreadFunc) (void*);
void start()
{
const int THREADS_NO=2;
pthread_t* threads = new pthread_t[THREADS_NO];
int ret;
volatile int i;
for (i = 0; i THREADS_NO; ++i)
{
ret = pthread_create(threads+i, NULL, shared_task_handler, NULL);
if (ret != 0)
{
printf("pthread create_shared error=%d\n", ret);
}
}
i = 100;
ret = pthread_create(threads+i, NULL, exclusive_task_handler, NULL);
if (ret != 0)
{
printf("pthread create_exclusive error=%d\n", ret);
}
}
};
int main()
{
Test tmptest;
tmptest.start();
while(1)
{
sleep(100);
}
}
运行结果:
[1257927661]r_lock[thread_0xb7c9fba0] r=1 w=0
[1257927661]r_lock[thread_0xb749eba0] r=2 w=0
[1257927662]r_unlock[thread_0xb7c9fba0] r=1 w=0
[1257927662]r_unlock[thread_0xb749eba0] r=0 w=0
r_unlock[thread_0xb749eba0] rd_cnt=0, so singal to wr_cnt[0]
=====[1257927663]w_lock[thread_0xb6c9dba0] r=0 w=1
===== w_lock[thread_0xb6c9dba0] get ok r=0 w=1
[1257927663]r_lock[thread_0xb749eba0] r=1 w=1
r_lock wait for wr_cnt[1]
[1257927663]r_lock[thread_0xb7c9fba0] r=2 w=1
r_lock wait for wr_cnt[1]
=====[1257927664]w_unlock[thread_0xb6c9dba0] r=2 w=0, then broadcast
[1257927665]r_unlock[thread_0xb749eba0] r=1 w=0
[1257927665]r_unlock[thread_0xb7c9fba0] r=0 w=0
r_unlock[thread_0xb7c9fba0] rd_cnt=0, so singal to wr_cnt[0]
[1257927666]r_lock[thread_0xb749eba0] r=1 w=0
[1257927666]r_lock[thread_0xb7c9fba0] r=2 w=0
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/104678/showart_2091760.html |
|