问题描述
如果我如下图所示两次调用EnterCriticalSection并一次调用LeaveCriticalSection会发生什么?
执行LeaveCriticalSection后,关键节是否仍会锁定或释放?
EnterCriticalSection
EnterCriticalSection
LeaveCriticalSection
可以请任何一个人澄清吗?
谢谢
What happens if I call EnterCriticalSection twice and LeaveCriticalSection once as shown below?
After executing LeaveCriticalSection, will the critical section still locked or released?
EnterCriticalSection
EnterCriticalSection
LeaveCriticalSection
Can any one please clarify?
Thanks
推荐答案
#include <windows.h>
#include <stdio.h>
CRITICAL_SECTION sectionA;
LONG WINAPI func(LONG);
int wmain(void)
{
HANDLE hThread;
DWORD dwordThreadID;
long i = 50;
printf("The current thread ID is %u\n", GetCurrentThreadId());
InitializeCriticalSection(§ionA);
hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)func,NULL,0,&dwordThreadID);
CloseHandle(hThread);
while(i--)
{
EnterCriticalSection(§ionA);
printf("Main Thread Entered : Locked Section A for (%u) \n", GetCurrentThreadId());
EnterCriticalSection(§ionA);
printf("Again Thread Entered : Locked Section A for (%u) \n", GetCurrentThreadId());
LeaveCriticalSection(§ionA);
printf("Main Thread releasing (%u) critical sections\n", GetCurrentThreadId());
// Remove this section and see
// LeaveCriticalSection(§ionA);
Sleep(200);
};
return 0;
}
LONG WINAPI func(LONG lParam)
{
long l=50;
while(l--)
{
printf("Thread Trying to access \n", GetCurrentThreadId());
EnterCriticalSection(§ionA);
printf("Thread2 Entered : Locked Section A for (%u) \n", GetCurrentThreadId());
EnterCriticalSection(§ionA);
printf("Thread2 Entered : Locked Section A for (%u) \n", GetCurrentThreadId());
LeaveCriticalSection(§ionA);
// Remove this section and see
// LeaveCriticalSection(§ionA);
printf("Thread2 releasing (%u) critical sections\n", GetCurrentThreadId());
Sleep(200);
};
}
希望这对您有帮助...
Hope this helps...
for(.,.,.)
{
EnterCriticalSection(.);
EnterCriticalSection(.);
LeaveCriticalSection(.);
}
只有一个线程:因此它将很好地运行循环.每次迭代将添加2个删除对象.
Wen确实存在,您还有许多待处理的锁.
在其他情况下,例如
there is just one thread: so it will run the loop nicely. It will add 2 remove one for each iteration.
Wen it exists, you''re left with a number of lock pending.
In anoter case like
EnterCriticalSection(.);
for(.,.,.)
{
EnterCriticalSection(.);
LeaveCriticalSection(.);
}
LeaveCriticalSection(.)
一切都很好.当然,内部Enter/Leave在这种情况下没有实际作用,但是它们可以保留在可以在循环内或循环外调用的函数体内.
通常,一个好的做法是将相等数量的Enter/Leave放入相同的作用域({}
对),或者让它们由堆栈上的变量构造/销毁管理,例如
everithing is fine. Of course, the inner Enter/Leave in this case have no practical effect, but they can stay inside a function body that can be called either inside or outside the loop.
In general a good practice is to place an equal number of Enter/Leave into a same scope ( {}
pairs) or let them be managed by a on-stack variable contruction / destruction, like
/// RAII enter/leave
class ccs_locker
{
CRITICAL_SECTION* pcs;
public:
ccs_locker(CRRITICAL_SECTION& cs) :pcs(&cs) { EnterCriticalSection(pcs); }
~ccs_unlocker() { LeaveCriticaSection(pcs); }
private:
/// disable copy and assign
ccs_locker(const ccs_locker&);
ccs_locker& operator=(const ccs_locker&);
};
/// CRITSEC initializer
class criticalsection: public CRITICAL_SECTION
{
public:
criticalsection() { InitializeCriticalSection(this); }
~criticalsection() { DeleteCriticalSection(this); }
private:
//disable copy and assign
criticalsection(const criticalsection&);
criticalsection& operator=(const criticalsection&);
};
///now a proper always good code
{
criticalsection cs;
ccs_locker lock1(cs);
for(...)
{
ccs_locker lock2(cs);
...
if(...) return;
...
if(...) throw ...;
...
if(...) break;
...
}
return;
}
道德:无论您如何返回,抛出或中断:析构函数都会始终调整调用对.
Moral: no matter how you return, throw or break: destructor will always adjust the call pairs.
这篇关于如果我两次调用EnterCriticalSection和一次LeaveCriticalSection会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!