一:实验目的
(1)掌握线程的创建与撤销。
(2)熟悉Windows系统提供的线程互斥API。
二:相关知识点
1.临界区对象(CriticalSection)
初始化临界(InitializeCriticalSection())
进⼊临界区(hEnterCriticalSection ())
退出临界区( LeaveCriticalSection ())
删除临界区 (DeleteCriticalSection())等API函数。
1.初始化临界区
InitializeCriticalSection()⽤于初始化临界区对象。
原型:
VOID InitializeCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
2.进⼊临界区
EnterCriticalSection()等待进⼊临界区的权限,当获得该权限后进⼊临界区。
原型:
VOID EnterCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
3.退出临界区
LeaveCriticalSection ()释放临界区的使⽤权限。
原型:
VOID LeaveCriticalSection (
LPCRITICAL_SECTION lpCriticalSection );
4.删除临界区
DeleteCri2calSec2on()删除与临界区有关的所有系统资源。
原型:
VOID DeleteCri2calSec2on(
LPCRITICAL_SECTION lpCri2calSec2on
);
以上函数均没有返回值
2.互斥对象
互斥对象(Mutex)包括创建互斥对象(CreateMutex())、打开互斥对象(OpenMutex())及释 放互斥对象(ReleaseMutex())API函数。
1.创建互斥对象
CreateMutex()⽤于创建⼀个互斥对象。
原型:
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexASributes,
BOOL bInitialOwner,
LPCTSTR lpName
);
2.打开互斥对象
OpenMutex()⽤于打开⼀个互斥对象。
原型:
HANDLE OpenMutex(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCTSTR lpName
);
3. 释放互斥对象
ReleaseMutex() ⽤于释放互斥对象。
原型:
BOOL ReleaseMutex(
HANDLE hMutex;
);
三、实验内容
完成两个⼦线程之间的互斥。在主线程中使⽤系统调⽤ CreateThread()创建两个⼦线程,并使两个⼦ 线程互斥的使⽤全局变量 count。
四、实验要求
能正确的使⽤临界区对象,包括初始化临界区 InitializeCriticalSection()、进⼊临界区 EnterCriticalSection()、退出临界区 LeaveCritical()及删除临界区 DeleteCriticalSection() 进⼀步理解线程 的互斥。
五、部分代码及运行结果
LPCRITICAL_SECTION CriticalSection; //定义指向临界区对象的地址指针
CRITICAL_SECTION Critical; //定义临界区
CriticalSection= &Critical; //将指向临界区对象的指针指向临界区
InitializeCriticalSection(CriticalSection); //初始化临界区
h1=CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)func1,
(LPVOID)NULL,
0,&dwThreadID1); //创建线程 func1
if (h1==NULL) printf("Thread1 create FAIL!\n");
else printf("Thread1 create Success!\n");
h2=CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)func2,
(LPVOID)NULL,
0,&dwThreadID2); //创建线程 func2
if (h2==NULL) printf ("Thread2 create FAIL!\n");
else printf ("Thread2 create Success!\n");
Sleep(1000);
CloseHandle(h1);
CloseHandle(h2);
DeleteCriticalSection(CriticalSection); //删除临界区
ExitThread(0);
return nRetCode;
}
void func2()
{ int r2;
EnterCriticalSection (CriticalSection); //进入临界区
r2=count;
_sleep(100);
r2=r2+1;
count=r2;
printf("count in func2=%d\n",count);
LeaveCriticalSection (CriticalSection); //退出临界区
}
void func1()
{
int r1;
EnterCriticalSection (CriticalSection); //进入临界区
r1=count;
_sleep(500);
r1=r1+1;
count=r1;
printf("count in func1=%d\n",count);
LeaveCriticalSection (CriticalSection);
}
运行结果
六、实验总结
我认为此次实验最重要的是将各个函数的原型记住,能够认清并掌握运用各个函数所能实现的功能。