Section和一次LeaveCriticalSection会发

Section和一次LeaveCriticalSection会发

本文介绍了如果我两次调用EnterCriticalSection和一次LeaveCriticalSection会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我如下图所示两次调用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(&sectionA);
	hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)func,NULL,0,&dwordThreadID);
	CloseHandle(hThread);
	while(i--)
	{
		EnterCriticalSection(&sectionA);
		printf("Main Thread Entered : Locked Section A for (%u) \n", GetCurrentThreadId());
		EnterCriticalSection(&sectionA);
		printf("Again Thread Entered : Locked Section A for (%u) \n", GetCurrentThreadId());
		LeaveCriticalSection(&sectionA);
		printf("Main Thread releasing  (%u) critical sections\n", GetCurrentThreadId());
		// Remove this section and see
		// LeaveCriticalSection(&sectionA);
		Sleep(200);
	};
	return 0;
}
LONG WINAPI func(LONG lParam)
{
	long l=50;
	while(l--)
	{
		printf("Thread Trying to access \n", GetCurrentThreadId());
		EnterCriticalSection(&sectionA);
		printf("Thread2 Entered : Locked Section A for (%u) \n", GetCurrentThreadId());
		EnterCriticalSection(&sectionA);
		printf("Thread2 Entered : Locked Section A for (%u) \n", GetCurrentThreadId());
		LeaveCriticalSection(&sectionA);
		// Remove this section and see
		// LeaveCriticalSection(&sectionA);
		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会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-04 19:52