在我的多线程服务器中,我有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);
...
...
}
答案 0 :(得分:1)
您当前的解决方案可能有dead lock个案例。如果你有两个(或更多)CSType
,这将以不同的顺序锁定,你将最终陷入死锁。最好的方法是原子地锁定它们。您可以在boost thread库中查看此示例。 shared_lock和unique_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
}