线程安全std::队列类c++17



queue_safe.cpp

#pragma once
#include <iostream>
#include <queue>
#include <string>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include "queue_safe.h"
void SafeQueue::initialize() {
/* initialize a std::queue */
safe_queue = {};

}
std::string SafeQueue::get() {
std::unique_lock<std::mutex> condition_lock(queue_lock);
/* wait 20 seconds */
std::chrono::system_clock::time_point wait = std::chrono::system_clock::now() + std::chrono::system_clock::duration(20);
while (safe_queue.empty()) {
if (ready.wait_until(condition_lock, wait) == std::cv_status::timeout) {
/* timeout was reached, no items left */
std::cout << "no items left in queue..." << std::endl;
}
std::string element = safe_queue.front();
safe_queue.pop();
return element;
}
/* not empty, return an element */

std::string element = safe_queue.front();
safe_queue.pop();
return element;
}
void SafeQueue::put(std::string& element) {
/* does not need to be thread-safe */
safe_queue.push(element);
}
uint8_t SafeQueue::empty() {
std::unique_lock<std::mutex> condition_lock(queue_lock);

if (safe_queue.size() == 0) {
return 1;
}
return 0;
}

queue_safe.h

#pragma once
#include <string>
#include <mutex>
#include <queue>
#include <condition_variable>
class SafeQueue {
public:
std::condition_variable ready;
std::mutex queue_lock;
std::queue<std::string> safe_queue;
uint8_t empty();
void initialize();
void put(std::string& element);
std::string get();
};

这显示了我从队列中安全获取字符串的代码。我想最多等待20秒,让一个元素可用,所以我使用了一个条件变量,一个唯一的锁,最后是wait_until。据我所知,我不需要围绕push(add)函数的互斥。目标:创建一个线程安全队列,该队列在指定时间段(此处为20秒)后超时
问题:这真的是线程安全吗?我是否需要一个围绕push函数的互斥/保护,如果需要,为什么
好的,所以1)为了可读性的目的,我需要使用bool而不是无符号的int,2)我需要同步推送和弹出,3)时间点不是真正的20秒。4) 我需要处理"虚假唤醒">

据我所知,我不需要围绕push(add)函数的互斥。

你知道错了。

这真的是线程安全吗?

否。

我需要一个围绕推送函数的互斥/保护吗

是。

为什么?

因为未按顺序修改容器会导致未定义的行为。std::queue::push修改容器。