使函数异常安全

时间:2014-01-22 20:29:45

标签: c++ wrapper critical-section

在我的多线程服务器中,我有somefunction(),需要使用EnterCriticalSection保护两个独立的全局数据。

somefunction()
{
  EnterCriticalSection(&g_List); 
  ...
  EnterCriticalSection(&g_Variable); 
   ...
  LeaveCriticalSection(&g_Variable);
   ...  
  LeaveCriticalSection(&g_List);
}

根据更好的程序员的建议,我将使用RAII包装器。例如:

class Locker
{
  public:
  Locker(CSType& cs): m_cs(cs)
  {
    EnterCriticalSection(&m_cs);
  }
  ~Locker()
  {
    LeaveCriticalSection(&m_cs);
  }
  private:
  CSType&  m_cs;
}

我的问题:somefunction()转换为此可以吗? (将2个储物柜放在一个功能中):

somefunction()
{
 // g_List,g_Variable previously initialized via InitializeCriticalSection

    Locker  lock(g_List);
    Locker  lock(g_Variable);
    ...
    ...
}

2 个答案:

答案 0 :(得分:1)

您当前的解决方案可能有dead lock个案例。如果你有两个(或更多)CSType,这将以不同的顺序锁定,你将最终陷入死锁。最好的方法是原子地锁定它们。您可以在boost thread库中查看此示例。 shared_lockunique_lock可以在延迟模式下使用,因此首先为所有互斥对象准备所有raii对象,然后在对lock函数的一次调用中以原子方式将它们全部锁定。

答案 1 :(得分:1)

只要您在线程中保持锁定顺序即可。你真的需要同时锁定它们吗?此外,使用范围锁定,您可以添加范围来控制何时解锁,如下所示:

{
    // use inner scopes to control lock duration
    {
        Locker lockList (g_list);
        // do something
    } // unlocked at the end

    Locker lockVariable (g_variable);
        // do something
}