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