我正在使用C++进行Win32多线程编程。
场景:
我有一个被多个线程使用的函数。
这个函数包含一个关键区域(或者任何可以锁定资源的构造)。
在关键区域中抛出异常。
此时,我需要在异常捕获块中解除锁定资源。
是否有其他方法可以实现这一点?我的意思是,假设我不想在catch块中记得释放锁定,是否有常见的方法来处理这个问题,以避免这种容易出错的情况?
我正在使用C++进行Win32多线程编程。
场景:
我有一个被多个线程使用的函数。
这个函数包含一个关键区域(或者任何可以锁定资源的构造)。
在关键区域中抛出异常。
此时,我需要在异常捕获块中解除锁定资源。
是否有其他方法可以实现这一点?我的意思是,假设我不想在catch块中记得释放锁定,是否有常见的方法来处理这个问题,以避免这种容易出错的情况?
这个想法是将获取和释放临界区的行为封装在一个对象中,这样构造该对象会获取临界区,销毁该对象会释放它。
struct CSHolder {
explicit CSHolder(CRITICAL_SECTION& cs): lock(cs) {
::EnterCriticalSection(&lock);
}
~CSHolder() { ::LeaveCriticalSection(&lock); }
CRITICAL_SECTION& lock;
};
CRITICAL_SECTION gLock;
void foo() {
CSHolder lockIt(gLock);
// lock is held until lockIt is destroyed
}
这个概念被称为RAII - 资源获取即初始化。它是现代C++中非常常见的习语。
CSingleLock
,如果您正在使用 boost,请查看 scoped_lock
。void f()
{
try
{
CSingleLock lock(&m_criticalSection, TRUE);
}
catch(/*some exception*/)
}
编写一个括号类,该类将关键部分作为构造函数参数。在构造函数中调用EnterCriticalSection,在析构函数中调用LeaveCriticalSection。如果抛出C++异常,堆栈展开将完成其余工作。