一个程序中最多可以mysql 最多创建多少表个读写锁

创建一个读写锁
ReadWriteLock rw = new ReentrantReadWriteLock();
import java.util.HashM
import java.util.M
import java.util.concurrent.locks.ReadWriteL
import java.util.concurrent.locks.ReentrantReadWriteL
public class ThreadCacheTest {
/**读写锁的应用
* @param args
private Map&String, Object& map = new HashMap&String, Object& ();
public static void main(String[] args) {
for(int i=1;i&=3;i++){
new Thread(new Runnable(){
public void run() {
System.out.println(Thread.currentThread().getName()+&取到数据--&+new ThreadCacheTest().getData(&aa&));
}).start();
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
public Object getData(String key){
ReadWriteLock rw1 = new ReentrantReadWriteLock();
//上一个读锁
rw1.readLock().lock();
Object value =
& &value = map.get(key);
&//要上写锁,先释放读锁
rw1.readLock().unlock();
rw1.writeLock().lock();
if(value == null){
value = &abc&;
rw1.writeLock().unlock();
rw1.readLock().lock();
}finally{&
rw1.readLock().unlock();
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:61237次
积分:2026
积分:2026
排名:第16770名
原创:141篇
转载:18篇
评论:24条
(5)(5)(1)(2)(4)(6)(6)(10)(3)(15)(17)(6)(9)(18)(33)(9)(9)(1)当前位置:&&编程语言>
windows下c/c++读写锁实现原理及代码参考
&&&&发布时间:&&
&&&&本文导语:&
读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。这种锁相对于自旋锁而言,能提高并发性,因为在多处理器系统中,它允...
& 读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。这种锁相对于自旋锁而言,能提高并发性,因为在多处理器系统中,它允许同时有多个读者来访问共享资源,最大可能的读者数为实际的逻辑CPU数。写者是排他性的,一个读写锁同时只能有一个写者或多个读者(与CPU数相关),但不能同时既有读者又有写者。现在Win32的API,用C++实现自己的读写锁。这组API包括:CreateMutex,CreateEvent,WaitForSingleObject,WaitForMultipleObjects,ResetEvent,ReleaseMutex,SetEvent,CloseHandle. & Windows在Vista 和 Server2008以后才开始提供读写锁API,即SRW系列函数(InitializeSRWLock, AcquireSRWLockShared, AcquireSRWLockExclusive等).那么如何实现一个自己的读写锁呢?读写锁的目的和要求 &读写锁的最基本目的是读锁可以共享,写锁必须独占.另外,还有两点需要特别考虑:1) 如果有写锁请求在等待,则新的读锁请求也应该等待.否则程序可能永远也没有机会获得写锁.2) 一旦写锁被释放,所有在等待中的读锁和写锁请求应该可以公平竞争,而不管请求的先后,只要之前已经在等待就应该有获得锁的机会.如果说第一点还可以再斟酌一下的话,第二点应该是必须要保证的.读写锁的实现总体思路比较简单:读写锁内部维护一些状态值,用临界端CRITICAL_SECTION保护这些状态值访问的原子性和事件对象配合实现等待.进入锁的情况:1) 如果当前锁状态为空闲,则不管写锁还是读锁请求都允许进入,并设置相应的状态值.2) 如果当前锁状态是读,新的写锁请求需要等待事件通知,并把写锁等待计数加一.3) 如果当前锁状态是读,新的读锁请求:(1) 如果没有写锁请求在等待,则允许读锁进入,并把读锁计数加一.(2) 如果有写锁请求正在等待,则等待事件通知,并读锁等待计数加一(这样做的目的如上文所述,要使写锁有机会进入).4) 如果当前锁状态为写,则不管读锁请求还是写锁请求,都等待事件通知并分别给读锁等待计数或者写锁等待计数加一.解锁的情况:如果锁释放时,读锁等待计数或者写锁等待计数不为0,则触发事件对象. & 我使用手动事件对象,这样的话一旦锁被释放,所有正在等待的锁请求都将被激活,然后重新以竞争临界段的方式竞争锁进入权以保证公平性.不管等待请求时的先后,只要是锁释放前进入等待状态则锁一旦释放获得进入权的机会是均等的. &读写锁实现参考代码1:#define RWLOCK_IDLE 0 /* 空闲 */
#define RWLOCK_R 0x01 /* 读锁 */
#define RWLOCK_W 0x02 /* 写锁 */
class RWLock
int _ /* 锁状态值 */
int _rlockC /* 读锁计数 */
int _rwaitingC /* 读等待计数 */
int _wwaitingC /* 写等待计数 */
HANDLE _ /* 通知事件 Event */
//HANDLE _stL /* 访问状态值互斥量 */ /* 如果需要等待超时,则用 Mutex */
CRITICAL_SECTION _stL
RWLock(void);
~RWLock(void);
void rlock();
void wlock();
void unlock();
RWLock::RWLock(void)
: _rlockCount(0),
_st(RWLOCK_IDLE),
_rwaitingCount(0),
_wwaitingCount(0)
//_stLock = CreateMutex(NULL, FALSE, NULL);
//assert(_stLock != INVALID_HANDLE_VALUE);
InitializeCriticalSection(&_stLock);
* 假设当前有多个读锁请求正在等待写锁释放,那么当写锁被释放时,所有这些读锁都应该有机会获得执行.
_ev = CreateEvent(NULL, TRUE, FALSE, NULL);
assert(_ev != INVALID_HANDLE_VALUE);
RWLock::~RWLock(void)
//CloseHandle(_stLock);
DeleteCriticalSection(&_stLock);
CloseHandle(_ev);
void RWLock::rlock()
bool isWaitReturn =
//WaitForSingleObject(_stLock, INFINITE);
EnterCriticalSection(&_stLock);
if(isWaitReturn)
* 等待事件返回,重新竞争锁.
--_rwaitingC
if(_st == RWLOCK_IDLE)
* 空闲状态,直接得到控制权
_st = RWLOCK_R;
_rlockCount++;
//ReleaseMutex(_stLock);
LeaveCriticalSection(&_stLock);
else if( _st == RWLOCK_R)
if(_wwaitingCount & 0)
* 有写锁正在等待,则一起等待,以使写锁能获得竞争机会.
++_rwaitingC
ResetEvent(_ev);
//SignalObjectAndWait(_stLock, _ev, INFINITE, FALSE);
LeaveCriticalSection(&_stLock);
* 虽然 LeaveCriticalSection() 和 WaitForSingleObject() 之间有一个时间窗口,
* 但是由于windows平台的事件信号是不会丢失的,所以没有问题.
WaitForSingleObject(_ev, INFINITE);
* 等待返回,继续尝试加锁.
isWaitReturn =
* 得到读锁,计数+1
//ReleaseMutex(_stLock);
LeaveCriticalSection(&_stLock);
else if(_st == RWLOCK_W)
* 等待写锁释放
++_rwaitingC
ResetEvent(_ev);
//SignalObjectAndWait(_stLock, _ev, INFINITE, FALSE);
LeaveCriticalSection(&_stLock);
WaitForSingleObject(_ev, INFINITE);
* 等待返回,继续尝试加锁.
isWaitReturn =
assert(0);
void RWLock::wlock()
bool isWaitReturn =
//WaitForSingleObject(_stLock, INFINITE);
EnterCriticalSection(&_stLock);
if(isWaitReturn) --_wwaitingC
if(_st == RWLOCK_IDLE)
_st = RWLOCK_W;
//ReleaseMutex(_stLock);
LeaveCriticalSection(&_stLock);
++_wwaitingC
ResetEvent(_ev);
//SignalObjectAndWait(_stLock, _ev, INFINITE, FALSE);
LeaveCriticalSection(&_stLock);
WaitForSingleObject(_ev, INFINITE);
isWaitReturn =
void RWLock::unlock()
//WaitForSingleObject(_stLock, INFINITE);
EnterCriticalSection(&_stLock);
if(_rlockCount & 0)
/* 读锁解锁 */
if( 0 == _rlockCount)
_st = RWLOCK_IDLE;
/* 释放 */
if( _wwaitingCount & 0 || _rwaitingCount & 0 )
* 此时有锁请求正在等待,激活所有等待的线程.(手动事件).
* 使这些请求重新竞争锁.
SetEvent(_ev);
/* 空闲 */
/* 还有读锁 */
_st = RWLOCK_IDLE;
/* 写锁解锁 */
if( _wwaitingCount & 0 || _rwaitingCount & 0 )
* 如果在占有互斥量_stLock的情况下,触发事件,那么可能会使一些锁请求不能得到竞争机会.
* 假设调用unlock时,另一个线程正好调用rlock或者wlock.如果不释放互斥量,只有之前已经等待的锁请求有机会获得锁控制权.
SetEvent(_ev);
/* 空闲 */
//ReleaseMutex(_stLock);
LeaveCriticalSection(&_stLock);
}读写锁参考代码2:class ReadWriteLock
int m_currentL
int m_readC
HANDLE m_unlockE
HANDLE m_accessM
CRITICAL_SECTION m_csStateC
ReadWriteLock
m_currentLevel = LOCK_LEVEL_NONE;
m_readCount = 0;
m_unlockEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
m_accessMutex = ::CreateMutex( NULL, FALSE, NULL );
::InitializeCriticalSection( &m_csStateChange );
~ReadWriteLock
::DeleteCriticalSection( &m_csStateChange );
if(m_accessMutex) ::CloseHandle( m_accessMutex );
if(m_unlockEvent) ::CloseHandle( m_unlockEvent );
bool lock(level, timeout = INFINITE)
bool bresult =
DWORD waitResult = 0;
waitResult = ::WaitForSingleObject( m_accessMutex, timeout );
if(waitResult != WAIT_OBJECT_0)
if(level==LOCK_LEVEL_READ && m_currentLevel != LOCK_LEVEL_WRITE )
::EnterCriticalSection( &m_csStateChange );
m_currentLevel =
m_readCount +=1;
::ReEvent( m_unlockEvent );
::LeaveCriticalSection( &m_csStateChange );
else if(level== LOCK_LEVEL_READ && m_currentLevel == LOCK_LEVEL_WRITE )
waitResult = ::WaitForSingleObject( m_unlockEvent, timeout );
if(waitResult== WAIT_OBJECT_0)
::EnterCriticalSection( &m_csStateChange );
m_currentLevel =
m_readCount +=1;
::ReEvent( m_unlockEvent );
::LeaveCriticalSection( &m_csStateChange );
else bresult =
else if(level== LOCK_LEVEL_WRITE && m_currentLevel == LOCK_LEVEL_NONE )
::EnterCriticalSection( &m_csStateChange );
m_currentLevel =
::ReEvent( m_unlockEvent );
::LeaveCriticalSection( &m_csStateChange );
else if(level== LOCK_LEVEL_WRITE && m_currentLevel != LOCK_LEVEL_NONE )
waitResult = ::WaitForSingleObject( m_unlockEvent, timeout );[Page]
if(waitResult==WAIT_OBJECT_0 )
::EnterCriticalSection( &m_csStateChange );
m_currentLevel =
::ReEvent( m_unlockEvent );
::LeaveCriticalSection( &m_csStateChange );
else bresult =
::ReleaseMutex( m_accessMutex );
bool unlock
::EnterCriticalSection( &m_csStateChange );
if(m_currentLevel== LOCK_LEVEL_READ )
m_readCount --;
if(m_readCount== 0)
m_currentLevel = LOCK_LEVEL_NONE;
::SetEvent (m_unlockEvent);
else if(m_currentLevel== LOCK_LEVEL_WRITE )
m_currentLevel = LOCK_LEVEL_NONE;
::SetEvent ( m_unlockEvent );
::LeaveCriticalSection( &m_csStateChange );
您可能感兴趣的文章:
本站()旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。本站()站内文章除注明原创外,均为转载,整理或搜集自网络.欢迎任何形式的转载,转载请注明出处.转载请注明:文章转载自:[]本文标题:
相关文章推荐:
特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!
(C)2012-,E-mail:www_169it_(请将#改为@)3723人阅读
随想录(103)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 &联系信箱:feixiaoxing @】& & 做游戏的同学想必对云风很熟悉。这一段时间他开发的skynet和ejoy2d两个软件框架在github上很火。其中skynet是为游戏服务器开发的,可以看成是一个service框架,ejoy2d是一个客户端的代码,内容不多,主要封装了opengl的一些接口,很多人不一定看得上。& & 我对游戏服务器不熟,但是服务器的相关代码还是看了一些的。之前vsftpd、redis、sshd、mysqld的代码也看过不少,多少知道一点。这次趁周末将skynet的代码看了一下,收获还是蛮多的。不管是Makefile、lua、service、networking,看得出来云风在服务器上面的造诣还是很深厚的。当然,最令我感兴趣的还是其中读写锁的写法,我也是第一次看到这种写法,和linux kernel中读写锁的写法也不一样。#ifndef _RWLOCK_H_
#define _RWLOCK_H_
struct rwlock {
static inline void
rwlock_init(struct rwlock *lock) {
lock-&write = 0;
lock-&read = 0;
static inline void
rwlock_rlock(struct rwlock *lock) {
for (;;) {
while(lock-&write) {
__sync_synchronize();
__sync_add_and_fetch(&lock-&read,1);
if (lock-&write) {
__sync_sub_and_fetch(&lock-&read,1);
static inline void
rwlock_wlock(struct rwlock *lock) {
while (__sync_lock_test_and_set(&lock-&write,1)) {}
while(lock-&read) {
__sync_synchronize();
static inline void
rwlock_wunlock(struct rwlock *lock) {
__sync_lock_release(&lock-&write);
static inline void
rwlock_runlock(struct rwlock *lock) {
__sync_sub_and_fetch(&lock-&read,1);
#endif& & 这段代码来自于rwlock.h这个文件。使用过读写锁的同学肯定比较清楚这几个函数的用法。一般先用rwlock_init初始化一下结构体。接着如果读锁的话,会使用rwlock_rlock和rwlock_runlock这对函数,当然使用写锁的话,会使用rwlock_wlock和rwlock_wunlock这对函数。读写锁一般用于读多写少的情况,因为这边没有使用基于调度的互斥函数,而是采取自旋的形式,所以这几个函数特别适合多核、且临界区内容操作特别少的情形。这也是这几个函数和普通读写锁的最大差别。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3570037次
积分:35699
积分:35699
排名:第108名
原创:357篇
评论:2478条
(2)(1)(5)(6)(2)(4)(1)(1)(1)(1)(1)(1)(3)(1)(1)(1)(1)(1)(1)(2)(1)(1)(1)(1)(3)(1)(1)(4)(4)(1)(7)(4)(16)(2)(1)(2)(3)(1)(1)(1)(2)(1)(3)(4)(5)(4)(3)(4)(4)(4)(7)(8)(9)(5)(6)(9)(8)(7)(7)(11)(19)(27)(30)(43)(30)(2)(1)(1)(1)(1)

我要回帖

更多关于 读写锁和互斥锁 的文章

 

随机推荐