[转]Linux 下的线程读写锁 - 空穴来风 - C++博客
2007-11-05 12:04
666 查看
导读:
有一种写优先读写锁,有如下特点:
1)多个读者可以同时进行读
2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)
3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)
在Solaris 中直接提供了读写锁, 但是在Linux 中只提供了线程的读写锁, 这里记录了一些读写锁的资料.
1.Solaris .vs. Linux Posix 库函数
Solaris 库(lib 线程) Linux POSIX 库(libp 线程) 操作
sema_destroy() sem_destroy() 销毁信号状态。
sema_init() sem_init() 初始化信号。
sema_post() sem_post() 增加信号。
sema_wait() sem_wait() 阻止信号计数。
sema_trywait() sem_trywait() 减少信号计数。
mutex_destroy() pthread_mutex_destroy() 销毁或禁用与互斥对象相关的状态。
mutex_init() pthread_mutex_init() 初始化互斥变量。
mutex_lock() pthread_mutex_lock() 锁定互斥对象和块,直到互斥对象被释放。
mutex_unlock() pthread_mutex_unlock() 释放互斥对象。
cond_broadcast() pthread_cond_broadcast() 解除对等待条件变量的所有线程的阻塞。
cond_destroy() pthread_cond_destroy() 销毁与条件变量相关的任何状态。
cond_init() pthread_cond_init() 初始化条件变量。
cond_signal() pthread_cond_signal() 解除等待条件变量的下一个线程的阻塞。
cond_wait() pthread_cond_wait() 阻止条件变量,并在最后释放它。
rwlock_init() pthread_rwlock_init() 初始化读/写锁。
rwlock_destroy() pthread_rwlock_destroy() 锁定读/写锁。
rw_rdlock() pthread_rwlock_rdlock() 读取读/写锁上的锁。
rw_wrlock() pthread_rwlock_wrlock() 写读/写锁上的锁。
rw_unlock() pthread_rwlock_unlock() 解除读/写锁。
rw_tryrdlock() pthread_rwlock_tryrdlock() 读取非阻塞读/写锁上的锁。
rw_trywrlock() pthread_rwlock_trywrlock() 写非阻塞读/写锁上的锁。
2.使用mutex 来实现
设置三个互斥信号量:
rwmutex?? ??? ?用于写者与其他读者/写者互斥的访问共享数据
rmutex?? ??? ?用于读者互斥的访问读者计数器readcount
nrmutex?? ??? ?用于写者等待已进入读者退出,所有读者退出前互斥写操作
var?? rwmutex,rmutex,nrmutex:semaphore:=1,1,1; ?
int?? readcount=0;
cobegin
?reader begin
? ?P(rwmutex);
? ?P(rmutex);
? ?readcount++;
? ?if (readcount == 1) P(nrmutex);? //有读者进入,互斥写操作
? ?V(rmutex);
? ?V(rwmutex);? //及时释放读写互斥信号量,允许其它读、写进程申请资源读数据;
? ?
? ?P(rmutex);
? ?readcount--;
? ?if(readcount == 0) V(nrmutex);? //所有读者退出,允许写更新
? ?V(rmutex);
?End
? ?writer begin
? ?P(rwmutex);??? //互斥后续其它读者、写者
? ?P(nrmutex);??? //如有读者正在读,等待所有读者读完
? ?写更新;
? ?V(nrmutex);??? //允许后续新的第一个读者进入后互斥写操作 ?
? ?V(rwmutex);??? //允许后续新读者及其它写者
?End ?
coend??
3. 利用pthread_cond_* &pthread_mutex_* 实现rw_lock
#include?#include?#include?#include?
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_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()
{
pthread_mutex_lock(&cnt_mutex);
rd_cnt--????????????if?(0?==?rd_cnt)
{
pthread_cond_signal(&rw_cond);
}
pthread_mutex_unlock(&cnt_mutex);
}
void?get_exclusive_lock()
{
pthread_mutex_lock(&cnt_mutex);
while?(rd_cnt+wr_cnt>0)
{
pthread_cond_wait(&rw_cond,&cnt_mutex);
}
wr_cnt++????????????pthread_mutex_unlock(&cnt_mutex);
}
void?release_exclusive_lock()
{
pthread_mutex_lock(&cnt_mutex);
wr_cnt--????????????pthread_cond_broadcast(&rw_cond);
pthread_mutex_unlock(&cnt_mutex);
}
~RWLock()
{
pthread_mutex_destroy(&cnt_mutex);
pthread_cond_destroy(&rw_cond);
}
};class?Test
{private?:????
RWLock?lock????
static?void*?shared_task_handler(void*?arg)
{
Test*?testptr?=?static_cast(arg);
testptr->lock.get_shared_lock();
//do?the?shared?task?here
testptr->lock.release_shared_lock();
}
static?void?*?exclusive_task_handler(void?*?arg)
{
Test*?testptr?=?static_cast(arg);
testptr->lock.get_exclusive_lock();
//do?the?exclusive?task?here
testptr->lock.release_exclusive_lock();
}public?:
typedef?void*?(*ThreadFunc)?(void*);
void?start()
{
srand(time(NULL));
const?int?THREADS_NO=rand()%100????????????pthread_t*?threads?=?new?pthread_t[THREADS_NO];
for(int?i=0?i {
ThreadFunc?tmpfunc?=?rand()%2??shared_task_handler?:?exclusive_task_handler;
if?(pthread_create(threads+i,NULL,tmpfunc,this))
{
cerr?<"pthread_create?fails"?<
exit(1);
}
}
for(int?i=0?i {
pthread_join(threads[i],NULL);
}
delete[]?threads;
}
};int?main()
{
Test?tmptest;
tmptest.start();
}
本文转自
http://www.cppblog.com/bigsml/archive/2006/09/07/12137.html
有一种写优先读写锁,有如下特点:
1)多个读者可以同时进行读
2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)
3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)
在Solaris 中直接提供了读写锁, 但是在Linux 中只提供了线程的读写锁, 这里记录了一些读写锁的资料.
1.Solaris .vs. Linux Posix 库函数
Solaris 库(lib 线程) Linux POSIX 库(libp 线程) 操作
sema_destroy() sem_destroy() 销毁信号状态。
sema_init() sem_init() 初始化信号。
sema_post() sem_post() 增加信号。
sema_wait() sem_wait() 阻止信号计数。
sema_trywait() sem_trywait() 减少信号计数。
mutex_destroy() pthread_mutex_destroy() 销毁或禁用与互斥对象相关的状态。
mutex_init() pthread_mutex_init() 初始化互斥变量。
mutex_lock() pthread_mutex_lock() 锁定互斥对象和块,直到互斥对象被释放。
mutex_unlock() pthread_mutex_unlock() 释放互斥对象。
cond_broadcast() pthread_cond_broadcast() 解除对等待条件变量的所有线程的阻塞。
cond_destroy() pthread_cond_destroy() 销毁与条件变量相关的任何状态。
cond_init() pthread_cond_init() 初始化条件变量。
cond_signal() pthread_cond_signal() 解除等待条件变量的下一个线程的阻塞。
cond_wait() pthread_cond_wait() 阻止条件变量,并在最后释放它。
rwlock_init() pthread_rwlock_init() 初始化读/写锁。
rwlock_destroy() pthread_rwlock_destroy() 锁定读/写锁。
rw_rdlock() pthread_rwlock_rdlock() 读取读/写锁上的锁。
rw_wrlock() pthread_rwlock_wrlock() 写读/写锁上的锁。
rw_unlock() pthread_rwlock_unlock() 解除读/写锁。
rw_tryrdlock() pthread_rwlock_tryrdlock() 读取非阻塞读/写锁上的锁。
rw_trywrlock() pthread_rwlock_trywrlock() 写非阻塞读/写锁上的锁。
2.使用mutex 来实现
设置三个互斥信号量:
rwmutex?? ??? ?用于写者与其他读者/写者互斥的访问共享数据
rmutex?? ??? ?用于读者互斥的访问读者计数器readcount
nrmutex?? ??? ?用于写者等待已进入读者退出,所有读者退出前互斥写操作
var?? rwmutex,rmutex,nrmutex:semaphore:=1,1,1; ?
int?? readcount=0;
cobegin
?reader begin
? ?P(rwmutex);
? ?P(rmutex);
? ?readcount++;
? ?if (readcount == 1) P(nrmutex);? //有读者进入,互斥写操作
? ?V(rmutex);
? ?V(rwmutex);? //及时释放读写互斥信号量,允许其它读、写进程申请资源读数据;
? ?
? ?P(rmutex);
? ?readcount--;
? ?if(readcount == 0) V(nrmutex);? //所有读者退出,允许写更新
? ?V(rmutex);
?End
? ?writer begin
? ?P(rwmutex);??? //互斥后续其它读者、写者
? ?P(nrmutex);??? //如有读者正在读,等待所有读者读完
? ?写更新;
? ?V(nrmutex);??? //允许后续新的第一个读者进入后互斥写操作 ?
? ?V(rwmutex);??? //允许后续新读者及其它写者
?End ?
coend??
3. 利用pthread_cond_* &pthread_mutex_* 实现rw_lock
#include?#include?#include?#include?
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_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()
{
pthread_mutex_lock(&cnt_mutex);
rd_cnt--????????????if?(0?==?rd_cnt)
{
pthread_cond_signal(&rw_cond);
}
pthread_mutex_unlock(&cnt_mutex);
}
void?get_exclusive_lock()
{
pthread_mutex_lock(&cnt_mutex);
while?(rd_cnt+wr_cnt>0)
{
pthread_cond_wait(&rw_cond,&cnt_mutex);
}
wr_cnt++????????????pthread_mutex_unlock(&cnt_mutex);
}
void?release_exclusive_lock()
{
pthread_mutex_lock(&cnt_mutex);
wr_cnt--????????????pthread_cond_broadcast(&rw_cond);
pthread_mutex_unlock(&cnt_mutex);
}
~RWLock()
{
pthread_mutex_destroy(&cnt_mutex);
pthread_cond_destroy(&rw_cond);
}
};class?Test
{private?:????
RWLock?lock????
static?void*?shared_task_handler(void*?arg)
{
Test*?testptr?=?static_cast(arg);
testptr->lock.get_shared_lock();
//do?the?shared?task?here
testptr->lock.release_shared_lock();
}
static?void?*?exclusive_task_handler(void?*?arg)
{
Test*?testptr?=?static_cast(arg);
testptr->lock.get_exclusive_lock();
//do?the?exclusive?task?here
testptr->lock.release_exclusive_lock();
}public?:
typedef?void*?(*ThreadFunc)?(void*);
void?start()
{
srand(time(NULL));
const?int?THREADS_NO=rand()%100????????????pthread_t*?threads?=?new?pthread_t[THREADS_NO];
for(int?i=0?i
ThreadFunc?tmpfunc?=?rand()%2??shared_task_handler?:?exclusive_task_handler;
if?(pthread_create(threads+i,NULL,tmpfunc,this))
{
cerr?<"pthread_create?fails"?<
exit(1);
}
}
for(int?i=0?i
pthread_join(threads[i],NULL);
}
delete[]?threads;
}
};int?main()
{
Test?tmptest;
tmptest.start();
}
本文转自
http://www.cppblog.com/bigsml/archive/2006/09/07/12137.html
相关文章推荐
- (转)Linux平台用C++封装线程读写锁
- linux c++多线程 线程私有数据 互斥量 条件变量 信号量 读写锁 自旋锁 屏障
- EVA QQ安装手册 - GCC/GNU/Linux Delphi/Window Java/Anywhere - C++博客
- Linux的线程同步对象:互斥量Mutex,读写锁,条件变量
- C++ linux线程安全单例Singleton
- C++文件读写总结 - IT-----无以言退 - 博客频道 - CSDN.NET
- Linux 下的线程读写锁
- Linux C++ 开发简介(包括Linux守护线程)
- Linux线程之线程池、高并发、线程数 C/C++ pthread 函数库
- Linux的线程同步对象:互斥量Mutex,读写锁,条件变量
- Linux /C/C++文件流读写操作的详解
- 用BoundsChecker检测内存泄漏 (zz) - 空穴来风 - C++博客
- 14.[个人]C++线程入门到进阶(14)----双线程读写队列数据
- Linux C/C++ 内存泄漏检测工具:Valgrind - 张宴的博客 - Web系统架构与底层研发
- linux 和 windows C++ 子线程编程中子线程的退出——总结
- 计算Linux系统和进程和线程的CPU及内存使用率(c++源码)
- C++进阶学习——线程基类的设计(Linux)
- Linux 下的线程读写锁
- linux线程读写锁
- 在Linux下快速获取某个线程的IO读写情况 推荐