现在的位置: 首页 > 综合 > 正文

Windows编程-- 用户方式中线程的同步—关键代码段(临界区)

2013年02月21日 ⁄ 综合 ⁄ 共 2502字 ⁄ 字号 评论关闭

可以从例子学习,更好的掌握

 

#include <windows.h>
#include
<iostream.h>
//两个线程的声明
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);

int tickets = 100;
CRITICAL_SECTION g_cs;
//定义一个临界区

int main()
{
HANDLE hThread1;
HANDLE hThread2;
hThread1
=CreateThread(NULL,0, Fun1Proc, NULL,0, NULL);
hThread2
=CreateThread(NULL,0, Fun2Proc, NULL,0, NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);

InitializeCriticalSection(
&g_cs); //初始化临界区
Sleep(4000);

DeleteCriticalSection(
&g_cs); //当临界区里没有资源时释放掉临界区(可以这样说吗)???

return 0;
}


DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{


while (TRUE)
{
EnterCriticalSection(
&g_cs); //该线程进入临界区
if (tickets > 0)
{
Sleep(
1);
cout
<< "Thread1 sell tickets:"<< tickets-- << endl;
}
else
{
break;
}
LeaveCriticalSection(
&g_cs); //退出临界区
}

return0;
}


DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{

while(TRUE)
{
EnterCriticalSection(
&g_cs); //该线程进入临界区
if(tickets > 0)
{
Sleep(
1);
cout
<< "Thread2 sell tickets:"<< tickets-- << endl;
}
else
{
break;
}
LeaveCriticalSection(
&g_cs); //退出临界区
}
return 0;

}

 

 

 

 应该注意的:

1 关键代码段(临界区)工作在用 用户方式下

2 关键代码段(临界区)是指一个小代码段,在代码够执行前。它必须独占对某些资源的访问权。

3 关键代码段是工作在用户方式下。同步速度较快,但在使用关键代码段时,很容易进入死锁状态。因为在等待进入关键代码段时无法设定超时值。

4 线程死锁 线程1拥有了临界区对象A。等待临界区对象B的拥有权。线程2拥有了临界区对象B,等待临界区对象A的拥有权,就造成了死锁

5 无法用它们对多个进程中的各个线程进行同步 

 

以下的例子就是进入了死锁。 


#include <windows.h>
#include
<iostream.h>
//1、两个线程的声明
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);

int tickets = 100;
CRITICAL_SECTION g_csA;
//2、定义两个临界区
CRITICAL_SECTION g_csB;

int main()
{
HANDLE hThread1;
HANDLE hThread2;
hThread1
=CreateThread(NULL,0, Fun1Proc, NULL,0, NULL);
hThread2
=CreateThread(NULL,0, Fun2Proc, NULL,0, NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);

InitializeCriticalSection(
&g_csA); //3、初始化临界区
InitializeCriticalSection(&g_csB);
Sleep(
4000);

DeleteCriticalSection(
&g_csA); //4、当临界区里没有资源时释放掉临界区
DeleteCriticalSection(&g_csB);
return 0;
}


DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{

// 11、两个临界区和两个线程会形成死机。线程在等待无法进入临界区g_csB。线程在等待无法进入临界区g_csA

while (TRUE)
{
EnterCriticalSection(
&g_csA); //5、该线程进入临界区g_csA
Sleep(1); //6、线程进入睡眠状态 线程时间片断结束线程开始
EnterCriticalSection(&g_csB); //9、线程进入临界区g_csB,但是临界区g_csB已被线程占用故只能等待时间片断交给线程
if (tickets > 0)
{
Sleep(
1);
cout
<< "Thread1 sell tickets:"<< tickets-- << endl;
}
else
{
break;
}
LeaveCriticalSection(
&g_csB); //退出临界区
LeaveCriticalSection(&g_csA);
}

return 0;
}


DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{

while(TRUE)
{
EnterCriticalSection(
&g_csB); //7、线程进入临界区g_csB
Sleep(1); //8、线程进入睡眠状态线程时间片断结束线程开始
EnterCriticalSection(&g_csA); //10、线程进入临界区g_csA 但是临界区g_csA已被线程占用故只能等待时间片断交给线程

if(tickets > 0)
{
Sleep(
1);
cout
<< "Thread2 sell tickets:"<< tickets-- << endl;
}
else
{
break;
}
LeaveCriticalSection(
&g_csA);
LeaveCriticalSection(
&g_csB); //退出临界区
}
return 0;
}

 

抱歉!评论已关闭.