在多线程环境中,确保代码的关键部分受到保护以防止数据损坏至关重要。其中一个关键部分是数据队列的管理。队列是一种遵循“先进先出”(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& 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中文网其他相关文章!