您的位置:首页 > 其它

读写锁和普通实现实现多线程读写者

2014-02-14 15:28 141 查看
许多大公司的经典面试题,多线程同步之读写者的两种实现。

 // 读写锁代码 : 定义控制台应用程序的入口点。

//

/************************************************************************/

/* SRW lock function Description 

AcquireSRWLockExclusive Acquires an SRW lock in exclusive mode. 

AcquireSRWLockShared Acquires an SRW lock in shared mode. 

InitializeSRWLock Initialize an SRW lock. 

ReleaseSRWLockExclusive Releases an SRW lock that was opened in exclusive mode. 

ReleaseSRWLockShared Releases an SRW lock that was opened in shared mode. 

读写锁实现读者写者的功能 vs2008+ 提供  

一个读者 俩写者

*/

/************************************************************************/

#include "stdafx.h"

#include <iostream>

#include <windows.h>  

#include <process.h>

using namespace std ;

SRWLOCK hSRWLock;//读写锁

int     shareData =0 ;//共享对象

const   int MAX_WRITE_COUT =10 ;//最大写入次数

CRITICAL_SECTION tipSection;

bool   bWriteOver=false ;//是否写结束

//设置控制台颜色

BOOL SetConsoleOutputColor(WORD  attr){

HANDLE stdHandle=::GetStdHandle(STD_OUTPUT_HANDLE) ;//获得标准输出句柄 

if(stdHandle==INVALID_HANDLE_VALUE){

return  FALSE ;

}

return SetConsoleTextAttribute(stdHandle,attr) ;

}

UINT  WINAPI WriteProc(LPVOID param){

    DWORD dwThreadID=GetCurrentThreadId() ;

for (int i
4000
=0;i<MAX_WRITE_COUT;i++){

EnterCriticalSection(&tipSection) ;

cout<<"写入线程"<<dwThreadID<<"等待写入数据"<<endl ; 

LeaveCriticalSection(&tipSection) ;

::AcquireSRWLockExclusive(&hSRWLock) ;//申请独占锁

SetConsoleOutputColor(FOREGROUND_BLUE) ;

cout<<"写入线程"<<dwThreadID<<"开始写入数据"<<endl ;

shareData=rand() ;

ReleaseSRWLockExclusive(&hSRWLock);//释放独占锁

}

bWriteOver=true ;

return 0;

}

UINT  WINAPI ReadProc(LPVOID param){

DWORD dwThreadID=GetCurrentThreadId() ;

while(!bWriteOver){

EnterCriticalSection(&tipSection) ;

cout<<"读者线程"<<dwThreadID<<"等待读取取数据"<<endl ;

LeaveCriticalSection(&tipSection) ;

::AcquireSRWLockShared(&hSRWLock);//申请共享锁

SetConsoleOutputColor(FOREGROUND_RED) ;

cout<<"读取线程"<<dwThreadID<<"读取数据:"<<shareData<<endl ;

::ReleaseSRWLockShared(&hSRWLock) ;//释放共享锁

}

return 0;

}

int _tmain(int argc, _TCHAR* argv[])

{  

HANDLE handleArr[5];

::InitializeSRWLock(&hSRWLock) ;  //初始化读写锁   自动释放

::InitializeCriticalSection(&tipSection) ;//初始化 CS

handleArr[0]=(HANDLE)_beginthreadex(NULL,0,WriteProc,NULL,0,NULL) ;

handleArr[1]=(HANDLE)_beginthreadex(NULL,0,ReadProc,NULL,0,NULL) ;

handleArr[2]=(HANDLE)_beginthreadex(NULL,0,ReadProc,NULL,0,NULL) ;

handleArr[3]=(HANDLE)_beginthreadex(NULL,0,ReadProc,NULL,0,NULL) ;

handleArr[4]=(HANDLE)_beginthreadex(NULL,0,ReadProc,NULL,0,NULL) ;

::WaitForMultipleObjects(5,handleArr,TRUE,0xFFFFFFFF) ; //等待激活

for (int i=0;i<5;i++)

{

CloseHandle(handleArr[i]) ;

}

return 0;

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/************************************************************************/
/* 读写者问题 2个写者 四个读者   
*  控制台输出的数据 需要通过唯一的 控制输出互斥资源控制 
/************************************************************************/
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <process.h>
using namespace std ;
HANDLE hHasWrite,hWrite ;//读写事件   
CRITICAL_SECTION dataSection,tipSection;//数据CS
int  intData= 0;  //数据  读者读取数据 写着修改数据

//设置控制台颜色
BOOL SetConsoleOutputColor(WORD  attr){
 HANDLE stdHandle=::GetStdHandle(STD_OUTPUT_HANDLE) ;//获得标准输出句柄 
     if(stdHandle==INVALID_HANDLE_VALUE){
return  FALSE ;
 }
 return SetConsoleTextAttribute(stdHandle,attr) ;
}
//写线程
UINT WINAPI WriteProc(LPVOID param){
DWORD dwThreadID=::GetCurrentThreadId() ;
//互斥 提示 防止提示错误
EnterCriticalSection(&tipSection) ;
SetConsoleOutputColor(FOREGROUND_RED) ;
cout<<"写入进程"<<dwThreadID<<"正在等待写入数据!"<<endl;
::LeaveCriticalSection(&tipSection) ; 
::WaitForSingleObject(hWrite,0xFFFFFFFF
b28f
)  ; //自动重置为没有信号的事件   

//互斥 提示 防止提示错误
EnterCriticalSection(&tipSection) ;
SetConsoleOutputColor(FOREGROUND_RED) ;
cout<<"写入进程"<<dwThreadID<<"正在写入!"<<endl;
::LeaveCriticalSection(&tipSection) ; 

//数据互斥  互斥的访问 被写入数据
EnterCriticalSection(&dataSection) ;
intData++ ;
LeaveCriticalSection(&dataSection) ;

SetEvent(hWrite) ;  //重置 事件有信号
SetEvent(hHasWrite) ;//设置信号 已经写入了

return 0 ;
}

//读取线程
UINT WINAPI ReadProc(LPVOID param){
DWORD dwThreadID=::GetCurrentThreadId() ;  

//互斥 提示
EnterCriticalSection(&tipSection) ;
SetConsoleOutputColor(FOREGROUND_GREEN) ;
cout<<"读取线程"<<dwThreadID<<"等待读取!"<<endl;
::LeaveCriticalSection(&tipSection) ; 

//等待有写入
::WaitForSingleObject(hHasWrite,0xFFFFFFFF) ;

//数据互斥
EnterCriticalSection(&dataSection) ;
//互斥 提示
EnterCriticalSection(&tipSection) ;
cout<<"读取线程"<<dwThreadID<<"读取到数据:"<<intData<<endl;
::LeaveCriticalSection(&tipSection) ; 
LeaveCriticalSection(&dataSection) ;
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{    
HANDLE handleArr[9] ;
::InitializeCriticalSection(&dataSection) ;
::InitializeCriticalSection(&tipSection) ;
hWrite=::CreateEvent(NULL,FALSE,TRUE,NULL);//两个写线程进行同步用 写线程并不能全部影响值
hHasWrite=::CreateEvent(NULL,TRUE,FALSE,NULL) ;//没有写入  初始化的时候是 
handleArr[0]=(HANDLE)_beginthreadex(NULL,0,WriteProc,NULL,0,NULL) ;  //写入
handleArr[1]=(HANDLE)_beginthreadex(NULL,0,WriteProc,NULL,0,NULL) ;
handleArr[2]=(HANDLE)_beginthreadex(NULL,0,ReadProc,NULL,0,NULL) ;  //读取
handleArr[3]=(HANDLE)_beginthreadex(NULL,0,ReadProc,NULL,0,NULL) ;
handleArr[4]=(HANDLE)_beginthreadex(NULL,0,ReadProc,NULL,0,NULL) ;
handleArr[5]=(HANDLE)_beginthreadex(NULL,0,ReadProc,NULL,0,NULL) ;
handleArr[6]=(HANDLE)_beginthreadex(NULL,0,ReadProc,NULL,0,NULL) ;
handleArr[7]=(HANDLE)_beginthreadex(NULL,0,ReadProc,NULL,0,NULL) ;
handleArr[8]=(HANDLE)_beginthreadex(NULL,0,ReadProc,NULL,0,NULL) ;
WaitForMultipleObjects(9,handleArr,TRUE,0xFFFFFFFF) ;//等待
for (int i=0;i<6;i++)
{
CloseHandle(handleArr[0]) ;
}
CloseHandle(hWrite) ;
CloseHandle(hHasWrite) ;
DeleteCriticalSection(&dataSection) ;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: