c++ - 线程崩溃后离开临界区

标签 c++ multithreading winapi synchronization critical-section

我有线程执行列表中的命令

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/

相关文章:

c# - 如何正确退出多线程程序

android - 来自另一个线程的回调导致异常

c++ - VerQueryValueA 在资源 block 外写入无效内存

c# - 如何以编程方式清除 Windows 下的回收站?

c - 如何根据扩展名动态获取文件名?

c++ - QString& 和 QString & 有区别吗?

c++ - 模板类成员函数初始化

c++ - 通过引用传递结构并分配字符串

C#:如何从另一个线程访问主 UI 线程中的整数?

c++ - 将 std::ispunct 作为参数传递给 remove_copy_if() 无法编译