[原创]VC++十剑 - 多线程同步
一.临界区法
临界区(Critical Section)就如同一个厕所的蹲位,当一个人进入后,其他的人只能挨个的等待,即一次只能容纳一个人。
临界区(Critical Section)就如同一个厕所的蹲位,当一个人进入后,其他的人只能挨个的等待,即一次只能容纳一个人。
#include "stdafx.h"
#define BUFFER_LENGTH 50
CRITICAL_SECTION _globalCS; //全局临界区结果对象
CHAR szBuf[BUFFER_LENGTH];
//线程函数A,用于向字符缓冲区中填入字符‘A’
DWORD WINAPI FillAFunc(LPVOID lpParam)
{
BOOL * pIsUsingCS = (BOOL *)lpParam; //获取主线程中传入的参数,决定是否使用临界区
_try
{
if(* pIsUsingCS) //决定使用临界区
{
EnterCriticalSection(&_globalCS);
}
for(int i=0;i<BUFFER_LENGTH;i++)
{
szBuf[i] = 'A';
printf("线程A:szBuf[%d] = '%C'\n",i,'A');
Sleep(10); //休眠线程10ms,留出CPU时间片共其它线程使用
}
}
_finally
{
if(* pIsUsingCS)
{
LeaveCriticalSection(&_globalCS);
}
}
return 0;
}
//线程函数B,用于向字符缓冲区中填入字符‘B’
DWORD WINAPI FillBFunc(LPVOID lpParam)
{
BOOL * pIsUsingCS = (BOOL *)lpParam; //获取主线程中传入的参数,决定是否使用临界区
_try
{
if(* pIsUsingCS) //决定使用临界区
{
EnterCriticalSection(&_globalCS);
}
for(int i=0;i<BUFFER_LENGTH;i++)
{
szBuf[i] = 'B';
printf("线程B:szBuf[%d] = '%C'\n",i,'B');
Sleep(10); //休眠线程10ms,留出CPU时间片共其它线程使用
}
}
_finally
{
if(* pIsUsingCS)
{
LeaveCriticalSection(&_globalCS);
}
}
return 0;
}
int main(int argc, char* argv[])
{
//初始化临界区
InitializeCriticalSection(&_globalCS);
HANDLE hThreads[2]; //线程句柄池,供后面检测所有的线程是否都已经运行结束使用
BOOL isUsingCS = FALSE; //在此决定是否使用临界区,TRUE:使用,FALSE:禁用
//启动所有线程
hThreads[0] = CreateThread(NULL,0,FillAFunc,&isUsingCS,0,NULL);
hThreads[1] = CreateThread(NULL,0,FillBFunc,&isUsingCS,0,NULL);
printf("所有线程都已经启动,等待它们完成。请稍候 \n");
//等待所有线程结束
WaitForMultipleObjects(2,hThreads,TRUE,INFINITE);
printf("完成,数据如下:\n");
for(int i=0;i<BUFFER_LENGTH;i++)
{
printf("%C",szBuf[i]);
}
//删除化临界区
DeleteCriticalSection(&_globalCS);
return 0;
}
#define BUFFER_LENGTH 50
CRITICAL_SECTION _globalCS; //全局临界区结果对象
CHAR szBuf[BUFFER_LENGTH];
//线程函数A,用于向字符缓冲区中填入字符‘A’
DWORD WINAPI FillAFunc(LPVOID lpParam)
{
BOOL * pIsUsingCS = (BOOL *)lpParam; //获取主线程中传入的参数,决定是否使用临界区
_try
{
if(* pIsUsingCS) //决定使用临界区
{
EnterCriticalSection(&_globalCS);
}
for(int i=0;i<BUFFER_LENGTH;i++)
{
szBuf[i] = 'A';
printf("线程A:szBuf[%d] = '%C'\n",i,'A');
Sleep(10); //休眠线程10ms,留出CPU时间片共其它线程使用
}
}
_finally
{
if(* pIsUsingCS)
{
LeaveCriticalSection(&_globalCS);
}
}
return 0;
}
//线程函数B,用于向字符缓冲区中填入字符‘B’
DWORD WINAPI FillBFunc(LPVOID lpParam)
{
BOOL * pIsUsingCS = (BOOL *)lpParam; //获取主线程中传入的参数,决定是否使用临界区
_try
{
if(* pIsUsingCS) //决定使用临界区
{
EnterCriticalSection(&_globalCS);
}
for(int i=0;i<BUFFER_LENGTH;i++)
{
szBuf[i] = 'B';
printf("线程B:szBuf[%d] = '%C'\n",i,'B');
Sleep(10); //休眠线程10ms,留出CPU时间片共其它线程使用
}
}
_finally
{
if(* pIsUsingCS)
{
LeaveCriticalSection(&_globalCS);
}
}
return 0;
}
int main(int argc, char* argv[])
{
//初始化临界区
InitializeCriticalSection(&_globalCS);
HANDLE hThreads[2]; //线程句柄池,供后面检测所有的线程是否都已经运行结束使用
BOOL isUsingCS = FALSE; //在此决定是否使用临界区,TRUE:使用,FALSE:禁用
//启动所有线程
hThreads[0] = CreateThread(NULL,0,FillAFunc,&isUsingCS,0,NULL);
hThreads[1] = CreateThread(NULL,0,FillBFunc,&isUsingCS,0,NULL);
printf("所有线程都已经启动,等待它们完成。请稍候 \n");
//等待所有线程结束
WaitForMultipleObjects(2,hThreads,TRUE,INFINITE);
printf("完成,数据如下:\n");
for(int i=0;i<BUFFER_LENGTH;i++)
{
printf("%C",szBuf[i]);
}
//删除化临界区
DeleteCriticalSection(&_globalCS);
return 0;
}