#include
<
stdio.h
>
#include < assert.h >
#include < windows.h >
#define LOCK_READ 0
#define LOCK_WRITE 1
class rwlock{
public :
rwlock();
~ rwlock();
public :
void lock ( int direct);
void unlock( int direct);
void lock_exclusive( void );
void unlock_exclusive( void );
void wrlock() { lock (LOCK_WRITE); }
void wrunlock() { unlock(LOCK_WRITE); }
void rdlock() { lock (LOCK_READ); }
void rdunlock() { unlock(LOCK_READ); }
private :
volatile LONG count;
volatile LONG direct;
HANDLE finish_event;
CRITICAL_SECTION start_lock;
};
rwlock::rwlock()
{
count = 0 ;
direct = 0 ;
finish_event = CreateEvent(NULL, FALSE, FALSE, NULL);
InitializeCriticalSection( & start_lock);
}
rwlock:: ~ rwlock()
{
assert(count == 0 );
CloseHandle(finish_event);
DeleteCriticalSection( & start_lock);
}
void rwlock:: lock ( int _direct)
{
EnterCriticalSection( & start_lock);
while (count > 0 &&
direct != _direct) {
WaitForSingleObject(finish_event, INFINITE);
}
direct = _direct;
InterlockedIncrement( & count);
LeaveCriticalSection( & start_lock);
}
void rwlock::unlock( int _direct)
{
assert(count > 0 );
assert(direct == _direct);
InterlockedDecrement( & count);
SetEvent(finish_event);
}
void rwlock::lock_exclusive( void )
{
EnterCriticalSection( & start_lock);
while (count > 0 &&
direct != _direct) {
WaitForSingleObject(finish_event, INFINITE);
}
InterlockedIncrement( & count);
}
void unlock_exclusive( void )
{
InterlockedDecrement( & count);
LeaveCriticalSection( & start_lock);
}
static DWORD CALLBACK ReadFunc(LPVOID lpVoid)
{
rwlock * plock = (rwlock * )lpVoid;
while ( 1 ) {
plock -> rdlock();
printf( " Start Read: threaid %x\n " , GetCurrentThreadId());
printf( " Call Read: threaid %x\n " , GetCurrentThreadId());
printf( " End Read: threaid %x\n " , GetCurrentThreadId());
plock -> rdunlock();
}
return 0 ;
}
int main( int argc, char * argv[])
{
DWORD id;
rwlock lock ;
for ( int i = 0 ; i < 10 ; i ++ ) {
HANDLE handle = CreateThread(NULL, 0 , ReadFunc, & lock , 0 , & id);
CloseHandle(handle);
}
while ( 1 ) {
lock .wrlock();
printf( " Start Write: threaid %x\n " , GetCurrentThreadId());
for ( int j = 0 ; j < 10 ; j ++ ) {
printf( " Call Write: threaid %x\n " , GetCurrentThreadId());
}
printf( " End Write: threaid %x\n " , GetCurrentThreadId());
lock .wrunlock();
}
return 0 ;
}
#include < assert.h >
#include < windows.h >
#define LOCK_READ 0
#define LOCK_WRITE 1
class rwlock{
public :
rwlock();
~ rwlock();
public :
void lock ( int direct);
void unlock( int direct);
void lock_exclusive( void );
void unlock_exclusive( void );
void wrlock() { lock (LOCK_WRITE); }
void wrunlock() { unlock(LOCK_WRITE); }
void rdlock() { lock (LOCK_READ); }
void rdunlock() { unlock(LOCK_READ); }
private :
volatile LONG count;
volatile LONG direct;
HANDLE finish_event;
CRITICAL_SECTION start_lock;
};
rwlock::rwlock()
{
count = 0 ;
direct = 0 ;
finish_event = CreateEvent(NULL, FALSE, FALSE, NULL);
InitializeCriticalSection( & start_lock);
}
rwlock:: ~ rwlock()
{
assert(count == 0 );
CloseHandle(finish_event);
DeleteCriticalSection( & start_lock);
}
void rwlock:: lock ( int _direct)
{
EnterCriticalSection( & start_lock);
while (count > 0 &&
direct != _direct) {
WaitForSingleObject(finish_event, INFINITE);
}
direct = _direct;
InterlockedIncrement( & count);
LeaveCriticalSection( & start_lock);
}
void rwlock::unlock( int _direct)
{
assert(count > 0 );
assert(direct == _direct);
InterlockedDecrement( & count);
SetEvent(finish_event);
}
void rwlock::lock_exclusive( void )
{
EnterCriticalSection( & start_lock);
while (count > 0 &&
direct != _direct) {
WaitForSingleObject(finish_event, INFINITE);
}
InterlockedIncrement( & count);
}
void unlock_exclusive( void )
{
InterlockedDecrement( & count);
LeaveCriticalSection( & start_lock);
}
static DWORD CALLBACK ReadFunc(LPVOID lpVoid)
{
rwlock * plock = (rwlock * )lpVoid;
while ( 1 ) {
plock -> rdlock();
printf( " Start Read: threaid %x\n " , GetCurrentThreadId());
printf( " Call Read: threaid %x\n " , GetCurrentThreadId());
printf( " End Read: threaid %x\n " , GetCurrentThreadId());
plock -> rdunlock();
}
return 0 ;
}
int main( int argc, char * argv[])
{
DWORD id;
rwlock lock ;
for ( int i = 0 ; i < 10 ; i ++ ) {
HANDLE handle = CreateThread(NULL, 0 , ReadFunc, & lock , 0 , & id);
CloseHandle(handle);
}
while ( 1 ) {
lock .wrlock();
printf( " Start Write: threaid %x\n " , GetCurrentThreadId());
for ( int j = 0 ; j < 10 ; j ++ ) {
printf( " Call Write: threaid %x\n " , GetCurrentThreadId());
}
printf( " End Write: threaid %x\n " , GetCurrentThreadId());
lock .wrunlock();
}
return 0 ;
}