windows平台下一个简单的解决读写同步问题的实现:(复习下windows的多线程以及同步)
稍后一段时间将贴出linux下的实现.
程序比较简单,下面的注释相信已经够了~
#include <windows.h>
/*如果我们要在不同进程的多线程使用该类,我们必须把该类放置到share memory中*/
#pragma once
class readerWriteLock
{
typedef HANDLE fd;
private:
long reader_wait;
long writer_wait;
fd reader_semaphore;
fd writer_semaphore;
long active_reader;
CRITICAL_SECTION cs;
public:
readerWriteLock()
{
reader_wait = writer_wait = active_reader = 0;
reader_semaphore = CreateSemaphore(NULL,0,MAXLONG,NULL);
writer_semaphore = CreateSemaphore(NULL,0,MAXLONG,NULL);
InitializeCriticalSection(&cs);
}
void wait_to_read()
{
bool _is_suspend =false;
EnterCriticalSection(&cs);
/*有写的线程在等候或者正有写线程正在操作,我们必须挂起该读线程*/
if( _is_suspend = ((writer_wait>0)|| (active_reader<0)) )
++reader_wait;
/*执行读线程*/
else
++active_reader;
LeaveCriticalSection(&cs);
if(_is_suspend)
WaitForSingleObject(reader_semaphore,INFINITE);
}
void wait_to_write()
{
bool _is_suspend =false;
EnterCriticalSection(&cs);
/*有读线程正在读操作或已有写线程正在写操作*/
if(_is_suspend=(active_reader != 0) )
++writer_wait;
/*写线程执行*/
else
active_reader=-1;
LeaveCriticalSection(&cs);
if(_is_suspend)
WaitForSingleObject(writer_semaphore,INFINITE);
}
void read_done()
{
EnterCriticalSection(&cs);
--active_reader;
/*如果没有读线程了并且有写线程在等待写操作*/
if(active_reader==0 && writer_wait > 0)
ReleaseSemaphore(writer_semaphore,1,NULL);
/*这种情况应该不可能出现*/
if(active_reader==0 && reader_wait > 0)
{
ReleaseSemaphore(reader_semaphore,reader_wait,NULL);
reader_wait = 0;
}
LeaveCriticalSection(&cs);
}
void write_done()
{
EnterCriticalSection(&cs);
--writer_wait;
active_reader = 0;
/*还有写线程正在等候*/
if(writer_wait>0)
ReleaseSemaphore(writer_semaphore,1,NULL);
/*还有读线程正在等候*/
if((writer_wait<=0) && (reader_wait>0))
{
ReleaseSemaphore(reader_semaphore,reader_wait,NULL);
reader_wait = 0;
}
LeaveCriticalSection(&cs);
}
~readerWriteLock()
{
CloseHandle(reader_semaphore);
CloseHandle(writer_semaphore);
DeleteCriticalSection(&cs);
}
};
下面的是测试代码
#include "readerWriteLock.h"
#include <iostream>
#include <process.h>
#pragma comment(linker, "/MT")
using std::cout;
using std::endl;
int arr[6];
readerWriteLock rwl;
CRITICAL_SECTION cs;
DWORD WINAPI read_thread_proc(PVOID par)
{
EnterCriticalSection(&cs);
int index =(int)par;
LeaveCriticalSection(&cs);
for(int i=2;i>0;--i)
{rwl.wait_to_read();
EnterCriticalSection(&cs);
for(int i=0;i<6;++i)
cout<<"arr["<<i<<"] is "<<arr[i];
cout<<endl;
LeaveCriticalSection(&cs);
rwl.read_done();
}
return 0;
}
DWORD WINAPI write_thread_proc(PVOID par)
{
int index =(int) par;
EnterCriticalSection(&cs);
LeaveCriticalSection(&cs);
for(int i=2;i>0;--i)
{rwl.wait_to_write();
for(int i=0;i<6;++i)
arr[i]++;
rwl.write_done();
}
return 0;
}
typedef unsigned (__stdcall *PTHREAD_START) (void *);
int main()
{ InitializeCriticalSection(&cs);
for(int i=0; i<6; ++i)
arr[i]=i;
HANDLE hds[6];
unsigned int tid[10];
for(int i=0; i<3 ;++i)
hds[i]=(HANDLE)_beginthreadex(NULL,0,(PTHREAD_START)read_thread_proc,(PVOID) (DWORD_PTR)i ,0,&tid[i]);
for(int i=3; i<6 ;++i)
hds[i]=(HANDLE)_beginthreadex(NULL,0,(PTHREAD_START)write_thread_proc,(PVOID) (DWORD_PTR)i ,0,&tid[i]);
WaitForMultipleObjects(6,hds,true,INFINITE);
for(int i=0;i<6;++i)
CloseHandle(hds[i]);
}