windows 读-写同步问题

来源:互联网 发布:畅璇网络棋牌 编辑:程序博客网 时间:2024/06/06 02:30

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]);
}