Linux 下的线程读写锁
来源:互联网 发布:2017淘宝防举报 编辑:程序博客网 时间:2024/05/20 18:46
Linux 下的线程读写锁
有一种写优先读写锁,有如下特点:
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
--------------------------
参考:
Solaris 執行緒與同步機制之實例
Posix线程编程指南
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 <pthread.h>
#include <cstdlib>
#include <ctime>
#include <iostream>
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<Test*>(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<Test*>(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<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);
}
}
for(int i=0; i<THREADS_NO; i++)
{
pthread_join(threads[i],NULL);
}
delete[] threads;
}
};
int main()
{
Test tmptest;
tmptest.start();
}
#include <cstdlib>
#include <ctime>
#include <iostream>
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<Test*>(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<Test*>(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<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);
}
}
for(int i=0; i<THREADS_NO; i++)
{
pthread_join(threads[i],NULL);
}
delete[] threads;
}
};
int main()
{
Test tmptest;
tmptest.start();
}
--------------------------
参考:
Solaris 執行緒與同步機制之實例
Posix线程编程指南
- Linux 下的线程读写锁
- Linux 下的线程读写锁
- Linux 下的线程读写锁
- Linux 下的线程读写锁
- Linux 下的线程读写锁
- [转]Linux 下的线程读写锁 - 空穴来风 - C++博客
- Linux线程的读写锁
- Linux下的读写锁
- Linux下线程同步对象(2)——读写锁
- Linux下线程同步对象(2)——读写锁
- LINUX下的线程同步——mutex和读写锁
- Linux线程同步-----读写锁
- linux编程---线程---读写锁
- linux下的读写锁pthread_mutex使用方法
- Linux线程浅析[线程的同步和互斥之线程读写锁]
- Linux下SRAM的读写
- Linux下SRAM的读写
- linux下配置文件的读写
- sql 存储过程 开发 常用语法记录 备忘
- jquery命令汇总
- (最新版本)redmine的安装与配置
- Silverlight作品:彩色卡片导航
- Java 信号量 Semaphore 介绍
- Linux 下的线程读写锁
- 第三章 流程控制
- JavaEE项目JDBC连接MySql数据库提示ClassNotFoundException的解决方案
- block 简单使用
- 网络基础之网桥和交换机的工作原理及区别
- 程序员老鸟写sql语句的经验之谈
- IOS设计模式之一:单例模式
- IOS设计模式之二:Delegate模式
- html标签select