(注:在写本篇学习笔记时,本人学习和参考了网络文章,并做了借鉴,感谢各位前辈的分享。如果本文对您有所帮助,您可以随意分享,如果发现文中有误,也请指教,谢谢。本文用到的调试工具:Microsoft Visual Studio 10,操作系统:Windows 7)
代码实现为:
#include "stdafx.h"
#include "process.h"
#include "windows.h"
static int gCount=0;
const int gSum=5;//总循环次数
const int gSleepTimes=100;
const int gEvyCount=3;
HANDLE g_hEventId[2];// 用于子线程之间的同步
HANDLE g_hFthEventId;// 用于父子线程的同步
CRITICAL_SECTION g_csThreadCode;
unsigned int __stdcall ThreadFunc(LPVOID pM)
{
int i=0;
int * w=(int *)pM;
HANDLE h1;
HANDLE h2;
if (*w==0)
{
h1=g_hEventId[0];
h2=g_hEventId[1];
}
else
{
h1=g_hEventId[1];
h2=g_hEventId[0];
}
printf("子线程[%d]启动\n",GetCurrentThreadId());
SetEvent(g_hFthEventId);
while(TRUE)
{
WaitForSingleObject(h1, INFINITE);
EnterCriticalSection(&g_csThreadCode);
if (h1==g_hEventId[0])
{
gCount++;
}
if (gCount>gSum)
{
LeaveCriticalSection(&g_csThreadCode);
SetEvent(h2);
break;
}
for (i=0;i<gEvyCount;i++)
{
Sleep(gSleepTimes);
printf("子线程[%d]第[%d]次循环[%d]次\n",GetCurrentThreadId(),gCount,i+1);
}
LeaveCriticalSection(&g_csThreadCode);
SetEvent(h2);
}
printf("子线程[%d]接收到消息,任务完成退出\n",GetCurrentThreadId());
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("---------------------------------------------------------------------\n");
printf(" 子线程之间同步问题 子线程1每次循环%d次 子线程2每次循环%d次 总循环%d次\n",gEvyCount,gEvyCount,gSum);
printf("---------------------------------------------------------------------\n");
int i=0;
HANDLE handleThreadId[2];
InitializeCriticalSection(&g_csThreadCode);
g_hFthEventId = CreateEvent(NULL, FALSE, FALSE, NULL);
g_hEventId[0] = CreateEvent(NULL, FALSE, TRUE, NULL);
g_hEventId[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
for(i=0;i<2;i++)
{
handleThreadId[i] = (HANDLE)_beginthreadex(NULL,0,ThreadFunc,&i,0,NULL);
WaitForSingleObject(g_hFthEventId, INFINITE);
}
WaitForMultipleObjects(2,handleThreadId, TRUE, INFINITE);
for(i=0;i<2;i++)
{
CloseHandle(handleThreadId[i]);
}
DeleteCriticalSection(&g_csThreadCode);
CloseHandle(g_hFthEventId);
CloseHandle(g_hEventId[0]);
CloseHandle(g_hEventId[1]);
printf("-----------OVER-------------\n");
getchar();
return 0;
}
运行结果为:
这道题目其实是对面试题一的扩展,由父子线程的同步变为子线程之间的同步。
在线程函数中,我们使用了关键代码段CriticalSection,使子线程之间对关键代码的操作互斥。
下面我们就来看下关键代码段的函数介绍:(以下介绍为转载,原文请参考:
http://blog.csdn.net/morewindows/article/details/7442639)
关键段CRITICAL_SECTION一共就四个函数,使用很是方便。下面是这四个函数的原型和使用说明。
函数功能:初始化
函数原型:
void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
函数说明:定义关键段变量后必须先初始化。
函数功能:销毁
函数原型:
void DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
函数说明:用完之后记得销毁。
函数功能:进入关键区域
函数原型:
void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
函数说明:系统保证各线程互斥的进入关键区域。
函数功能:离开关关键区域
函数原型:
void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);