[英]Is there any other way to destruct objects when they leave the function scope?
[英]Is there any way that Enter/LeaveCriticalSection could leave a handle behind
我的程序中包含以下代码:
EnterCriticalSection(&critsec[x]);
// stuff
LeaveCriticalSection(&critsec[x]);
它可以在99.999%的时间内正常工作,但有时似乎会留下手柄。 现在,我做了一些显而易见的事情,例如确保x在输入之间不改变值,并确保在“ //东西”中没有任何“返回”或“中断”,但是我想知道是否可能有东西否则会导致输入/离开对留下手柄。 可能是内存不足或操作系统中的某些计数器溢出或其他原因。
编辑:我是C ++的新手,该程序直到最近才从C转换。它在整个程序的任何地方都没有异常。
如果您没有明确删除关键部分,并且关键部分曾经有过争用,您将泄漏句柄。 当两个或多个线程尝试进入单个关键部分时重叠时,Windows关键部分的某些实现会分配信号量。
这不是泄漏。 更确切地说,如果“泄漏的”句柄的数量小于或等于您正在使用的全局关键节的数量,这并不是泄漏。
米克
有很多事情可能发生。
异常可能导致控制流在执行LeaveCriticalSection调用之前退出该块。 为避免此问题,您可以使用“资源获取为初始化(RAII)”模式来包装关键部分在基于堆栈的对象中的进入和退出。
但是,如果没有更完整的清单,就无法说出代码是否还有其他问题。
干杯
由于您在C ++领域,因此// stuff
部分的异常将跳过LeaveCriticalSection()
。 查找RAII(“资源获取即初始化”)作为防止这种情况发生的工具。 这是此类的一个简单示例:
class CriticalSectionLock {
public:
CriticalSectionLock(CRITICAL_SECTION& c) : cs_(c){EnterCriticalSection(&cs_);}
~CriticalSectionLock() {LeaveCriticalSection(&cs_);}
private:
CRITICAL_SECTION& cs_;
};
void f()
{
CriticalSectionLock lock(critsec[x])
// stuff
} // lock's destructor will automagically call LeaveCriticalSection()
附带说明:死锁有时会给人以某些锁没有正确解锁的印象。
最可能的原因是一个例外。 您是否正在捕获此函数中的异常以及它们是否调用Leave? 另外,请注意,最好使用CSingleLock类来锁定关键部分,而不是使用像这样的原始API。 通过使用CSingleLock,您可以在发生异常的情况下进行适当的清理。
扩展sbi的答案(正如您所说的,您是C ++的新手),异常会忽略从调用它的地方开始的其余代码,直到到达可以处理异常的地方(“捕获”)为止-唯一的例外是当异常将内存包装在堆栈中时-它调用堆栈变量的析构函数。
为了确保始终调用“ Leave”,请使用以下类:(缺少格式),然后将此类的实例和关键代码放入新的堆栈中。 这样可以确保在非异常和异常情况下都始终调用“ Leave”。
编辑:更新POC代码以反映评论。
class AutoCritical
{
public:
AutoCritical(CritSec * p_CritSec) : m_Sec(p_CritSec)
{ EnterCriticalSection(m_CritSec); };
~AutoCritical() { LeaveCriticalSection(m_CritSec); };
private:
CritSec * m_Sec;
};
呼叫地点:
// non-critical code ....
{ //open stack for critical code
AutoCritical a(&critsec[x]);
// do critical stuff here ...
} // close stack
您是否有可能因输入/离开不匹配而丢失了句柄,而是忘记了调用DeleteCriticalSection。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.