先做一点CreateEvent的实验:
HANDLE _event;
HANDLE _pthread;
DWORD WINAPI thread(void* lparam)
{
SetEvent(_event);
SetEvent(_event);
return 0;
}
int main(int argc, char* argv[])
{
_event = ::CreateEvent(NULL, FALSE, FALSE, NULL);
assert(_event != 0);
_pthread = CreateThread(NULL, 0, thread, NULL, 0, NULL);
assert(_pthread != 0);
Sleep(10000);
WaitForSingleObject(_event, INFINITE);
printf("the event done 1.\n");
WaitForSingleObject(_event, INFINITE);
printf("the event done 2.\n");
WaitForSingleObject(_pthread, INFINITE);
return 0;
}
读写锁实现源码:
#include <stdio.h>
#include <assert.h>
#include <windows.h>
class rwlock
{
public:
/**
* 读写锁状态:
* LOCK_READ: 读状态
* LOCK_WRITE: 写状态
*/
enum LOCK_TYPE { LOCK_READ = 0x12, LOCK_WRITE };
rwlock()
{
_count = 0;
_type = LOCK_READ;
_event = ::CreateEvent(NULL, FALSE, TRUE, NULL);
::InitializeCriticalSection(&_glock);
}
~rwlock()
{
assert(_count == 0);
::CloseHandle(_event);
::DeleteCriticalSection(&_glock);
}
public:
/* 写锁 */
void wrlock()
{
::EnterCriticalSection(&_glock);
/* 写锁阻塞条件很简单,只要有对锁定数据的读写操作就会阻塞 */
if (_count > 0) {
::WaitForSingleObject(_event, INFINITE);
}
::InterlockedDecrement(&_count);
_type = LOCK_WRITE;
::LeaveCriticalSection(&_glock);
}
/* 释放写锁 */
void wrunlock()
{
::InterlockedDecrement(&_count);
SetEvent(_event);
}
/* 读锁 */
void rdlock()
{
::EnterCriticalSection(&_glock);
/* 读锁的阻塞条件,_count == 0或者_count > 0 && _type == LOCK_READ */
if ((_count != 0) && (_count > 0 && _type != LOCK_READ)) {
::WaitForSingleObject(_event, INFINITE);
}
::InterlockedIncrement(&_count);
_type = LOCK_READ;
::LeaveCriticalSection(&_glock);
}
void rdunlock()
{
/* 释放读锁 */
::InterlockedDecrement(&_count);
SetEvent(_event);
}
private:
volatile LONG _count;
volatile LOCK_TYPE _type;
HANDLE _event;
CRITICAL_SECTION _glock;
};