キューの長さを制御する必要があるため、2次キャッシュは使用しません、つまりコンシューマースレッドは2次キャッシュとしてstd::vectorなどを使用しません。キャッシュを使用する場合は均一分散の問題を考慮する必要があります もちろん二次キャッシュを使用しても処理するデータの長さを制御することはできますが、処理は非常に複雑になります ここでは簡単な使用方法を示します. 他の効果が必要な場合は構築を参照してください。
#include <condition_variable>
#include <chrono>
#include <queue>
#include <mutex>
/*
* 有最大队列个数限制
*/
// 参数T需要能够拷贝,而且拷贝不会存在副作用
template <typename T>
class sync_queue {
public:
sync_queue(int queueMaxSize): m_queueMaxSize(queueMaxSize) { }
// 处理数据线程
template <typename Func>
typename std::result_of<Func(T)>::type readQueue(Func readFunc) {
T data;
// 取出数据, 然后处理数据
{
std::unique_lock<std::mutex> lock(m_queueMtx);
m_consumeCv.wait(lock, [this]{ return m_data.size() != 0; });
data = m_data.front();
m_data.pop();
}
m_produceCv.notify_one();
return readFunc(data);
}
// 生产数据线程, 返回值表示是否生产成功,如果超时就不会生产成功
template <typename Rep, typename Period>
bool writeQueue(T data, const std::chrono::duration<Rep, Period>& wait_time) {
// 预设一个消费者处理这个数据
{
std::unique_lock<std::mutex> lock(m_queueMtx);
auto success = m_produceCv.wait_for(lock, wait_time, [this]{ return m_data.size() <= m_queueMaxSize; });
if (!success) {
return false;
}
m_data.push(std::move(data));
}
m_consumeCv.notify_one();
return true;
}
private:
// 用来存储生产者存储的值
std::queue<T> m_data;
// 用来表示待处理的数据
int m_queueMaxSize;
// 用来队列保护
std::mutex m_queueMtx;
// 用来提醒当前可以消费
std::condition_variable m_consumeCv;
// 用来提醒当前可以生产
std::condition_variable m_produceCv;
};