繁体   English   中英

有什么方法可以使Enter / LeaveCriticalSection留下句柄

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM