首页  >  文章  >  后端开发  >  使用 `std::condition_variable::wait_for` 时如何防止 C 11 线程安全队列中出现段错误?

使用 `std::condition_variable::wait_for` 时如何防止 C 11 线程安全队列中出现段错误?

DDD
DDD原创
2024-11-01 11:49:30916浏览

How to Prevent Segfaults in a C  11 Thread-Safe Queue When Using `std::condition_variable::wait_for`?

C 11 中的线程安全队列

在多线程环境中,确保代码的关键部分受到保护以防止数据损坏至关重要。其中一个关键部分是数据队列的管理。队列是一种遵循“先进先出”(FIFO) 原则的数据结构。在 C 11 中实现线程安全队列涉及使用互斥体和条件变量等同步机制。

相关代码片段展示了使用 std::mutex 和 std::condition_variable 的线程安全队列。 enqueue 方法将一个项目添加到队列中,同时持有 qMutex 上的锁以保护队列。它还使用 populatedNotifier 条件变量通知任何等待线程。

出队方法从队列中检索项目。它获取 qMutex 上的唯一锁,检查队列是否为空,并在必要时使用 wait_for 函数进行超时等待。如果线程收到队列中有新项目的通知,它将退出等待并继续从队列中检索和删除项目。

但是,当队列为空时,会观察到段错误,这表明 wait_for 函数返回无需通知。这可能是由于虚假唤醒而发生的。

为了防止此问题,建议反转 while 循环的条件。不要“等待队列不为空”,而是在“队列为空”时等待。这确保循环在任何虚假唤醒后重新检查队列的空性。

这是出队方法的修订版本:

<code class="cpp">std::string FileQueue::dequeue(const std::chrono::milliseconds&amp; timeout)
{
    std::unique_lock<std::mutex> lock(qMutex);
    while (q.empty()) {
        if (populatedNotifier.wait_for(lock, timeout) == std::cv_status::no_timeout) {
            // Lock may have been released spuriously; recheck condition
            if (q.empty()) {
                return std::string();
            }
            std::string ret = q.front();
            q.pop();
            return ret;
        }
        else {
            return std::string();
        }
    }
    std::string ret = q.front();
    q.pop();
    return ret;
}</code>

这确保线程仅在以下情况下继续进行:队列不为空,避免了虚假唤醒引起的段错误。

以上是使用 `std::condition_variable::wait_for` 时如何防止 C 11 线程安全队列中出现段错误?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn