您的位置:首页 > 编程语言

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

2011-01-05 15:28 615 查看
可以从例子学习,更好的掌握

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: