使功能异常安全

make function exception-safe

本文关键字:安全 异常 功能      更新时间:2023-10-16

在我的多线程服务器中,我有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);
    ...
    ...
}

您的当前解决方案具有潜在的死锁情况。如果您有两个(或更多)CSType s,以这种方式锁定了不同的顺序,则最终会陷入死锁。最好的方法是将它们都锁定。您可以在Boost线程库中看到一个示例。shared_lock和unique_lock可以在延期模式下使用,因此首先您准备所有的raii对象为所有静音对象,然后在一个呼叫中锁定锁定功能,然后将它们全部锁定。

只要您在线程中保持锁定顺序相同,就可以。您是否真的需要同时锁定它们?另外,使用示波器锁,您可以添加范围来控制何时解锁,类似的东西:

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