posts - 1,  comments - 1,  trackbacks - 0
线程同步 之 EnterCriticalSection进入临界区

理解EnterCriticalSection 临界区

 

比如说我们定义了一个共享资源dwTime[100],两个线程ThreadFuncA和ThreadFuncB都对它进行读写操作。当我们想要保证 dwTime[100]的操作完整性,即不希望写到一半的数据被另一个线程读取,那么用CRITICAL_SECTION来进行线程同步如下:

第一个线程函数:

DWORD   WINAPI   ThreadFuncA(LPVOID   lp)
{
EnterCriticalSection(&cs);
...
//   操作dwTime
...
LeaveCriticalSection(&cs);
return   0;
}

写出这个函数之后,很多初学者都会错误地以为,此时cs对dwTime进行了锁定操作,dwTime处于cs的保护之中。一个“自然而然”的想法就是——cs和dwTime一一对应上了。

这么想,就大错特错了。dwTime并没有和任何东西对应,它仍然是任何其它线程都可以访问的。如果你像如下的方式来写第二个线程,那么就会有问题:

DWORD   WINAPI   ThreadFuncB(LPVOID   lp)
{
...
//   操作dwTime
...
return   0;
}

当线程ThreadFuncA执行了EnterCriticalSection(&cs),并开始操作dwTime[100]的时候,线程 ThreadFuncB可能随时醒过来,也开始操作dwTime[100],这样,dwTime[100]中的数据就被破坏了。

为了让CRITICAL_SECTION发挥作用,我们必须在访问dwTime的任何一个地方都加上 EnterCriticalSection(&cs)和LeaveCriticalSection(&cs)语句。所以,必须按照下面的方式来写第二个线程函数:

DWORD   WINAPI   ThreadFuncB(LPVOID   lp)
{
EnterCriticalSection(&cs);
...
//   操作dwTime
...
LeaveCriticalSection(&cs);
return   0;
}

这样,当线程ThreadFuncB醒过来时,它遇到的第一个语句是EnterCriticalSection(&cs),这个语句将对cs变量进行访问。如果这个时候第一个线程仍然在操作dwTime[100],cs变量中包含的值将告诉第二个线程,已有其它线程占用了cs。因此,第二个线程的 EnterCriticalSection(&cs)语句将不会返回,而处于挂起等待状态。直到第一个线程执行了 LeaveCriticalSection(&cs),第二个线程的EnterCriticalSection(&cs)语句才会返回,并且继续执行下面的操作。

这个过程实际上是通过限制有且只有一个函数进入CriticalSection变量来实现代码段同步的。简单地说,对于同一个 CRITICAL_SECTION,当一个线程执行了EnterCriticalSection而没有执行LeaveCriticalSection的时候,其它任何一个线程都无法完全执行EnterCriticalSection而不得不处于等待状态

再次强调一次,没有任何资源被“锁定”,CRITICAL_SECTION这个东东不是针对于资源的,而是针对于不同线程间的代码段的!我们能够用它来进行所谓资源的“锁定”,其实是因为我们在任何访问共享资源的地方都加入了EnterCriticalSection和 LeaveCriticalSection语句,使得同一时间只能够有一个线程的代码段访问到该共享资源而已(其它想访问该资源的代码段不得不等待)。

这就是使用一个CRITICAL_SECTION时的情况。你应该要知道,它并没有什么可以同步的资源的“集合”。这个概念不正确。

如果是两个CRITICAL_SECTION,就以此类推。

 

posted on 2010-01-18 17:30 苏勇 阅读(1111) 评论(1)  编辑 收藏 引用

FeedBack:
# re: 线程同步 之 EnterCriticalSection进入临界区
2015-03-07 10:35 | TTLOVESS
#include<windows.h>
#include<iostream.h>

DWORD WINAPI Fun1Proc( LPVOID lpParameter );
DWORD WINAPI Fun2Proc( LPVOID lpParameter );

int tickets=100;
CRITICAL_SECTION g_cs;
void main()
{
HANDLE hThread1,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);
}
DWORD WINAPI Fun1Proc( LPVOID lpParameter )
{
while(1)
{
EnterCriticalSection(&g_cs);
if(tickets)
{
Sleep(1);
cout<<"Thread 1 is selling:"<<tickets--<<endl;
}
else break;
LeaveCriticalSection(&g_cs);
}
return 0;
}
DWORD WINAPI Fun2Proc( LPVOID lpParameter )
{
while(1)
{
EnterCriticalSection(&g_cs);
if(tickets)
{
Sleep(1);
cout<<"Thread 2 is selling:"<<tickets--<<endl;
}
else break;
LeaveCriticalSection(&g_cs);
}
return 0;
}
博主,为什么我的线程同步的小代码运行结果只有一个进程运行  回复  更多评论
  
<2015年3月>
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

留言簿

随笔档案

文章档案

搜索

  •  

最新评论