我有线程执行列表中的命令
do
{
commandExec->criticalSection.EnterCS();
if (!commandExec->commands.empty())
{
commandExec->ExecuteCommand(commandExec->commands.front());
commandExec->commands.pop_front();
}
else
commandExec->criticalSection.SuspendThread();
commandExec->criticalSection.LeaveCS();
} while (commandExec->maintainCommandExecution);
第二个线程将命令添加到列表:
criticalSection.EnterCS();
commands.push_back(Command(code, parameters));
criticalSection.LeaveCS();
criticalSection.ResumeThread();
第一个线程在执行命令时可能崩溃,因此第二个线程无法访问临界区:
If a thread terminates while it has ownership of a critical section, the state of the critical section is undefined. Source
那么,处理这个问题的好方法是什么? 我能想到一些解决方案,但它们似乎很棘手(添加第三个线程、第二个关键部分等)
(criticalSection 它只是 CRITICAL_SECTION 的简单包装器)
最佳答案
您可以创建一个类 LockCriticalSection,它在构造函数中锁定临界区并在析构函数中解锁临界区。
然后,在您的代码中,您在要开始锁定的位置分配一个 LockCriticalSection 对象。当对象 LockCriticalSection 超出范围时(因为函数正确终止或因为异常),临界区将自动释放
以下是负责锁定和解锁临界区的代码:
/// \brief This class locks a critical section in the
/// constructor and unlocks it in the destructor.
///
/// This helps to correctly release a critical section in
/// case of exceptions or premature exit from a function
/// that uses the critical section.
///
///////////////////////////////////////////////////////////
class LockCriticalSection
{
public:
/// \brief Creates the object LockCriticalSection and
/// lock the specified CRITICAL_SECTION.
///
/// @param pCriticalSection pointer to the CRITICAL_SECTION
/// to lock
///
///////////////////////////////////////////////////////////
LockCriticalSection(CRITICAL_SECTION* pCriticalSection):
m_pCriticalSection(pCriticalSection)
{
EnterCriticalSection(pCriticalSection);
}
/// \brief Destroy the object LockCriticalSection and
/// unlock the previously locked CRITICAL_SECTION.
///
///////////////////////////////////////////////////////////
virtual ~LockCriticalSection()
{
LeaveCriticalSection(m_pCriticalSection);
}
private:
CRITICAL_SECTION* m_pCriticalSection;
};
这是根据您的问题修改后的源代码:
do
{
{
LockCriticalSection lock(&criticalSectionToLock);
while (!commandExec->commands.empty())
{
commandExec->ExecuteCommand(commandExec->commands.front());
commandExec->commands.pop_front();
}
} // here the critical section is released
// suspend thread here
} while (commandExec->maintainCommandExecution);
关于c++ - 线程崩溃后离开临界区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13279987/