Use atomic_flag para controlar la atomicidad
while (flag.test_and_set (std :: memory_order_acquire)); do lock
flag.clear (std :: memory_order_release); do desbloquear
Esto implica el problema del orden de la memoria, que se discutirá más adelante.
La cola adopta std :: queue, y luego el patrón decorador se implementa con genéricos de plantilla, correspondientes
- claro
- música pop
- empujar
- Talla
- La
longitud de la cola vacía se puede configurar, el valor predeterminado es 64, el
código es el siguiente
#pragma once
#include <pthread.h>
#include <queue>
// 封装一个简单的Mutex类
class SpinLock {
private:
std::atomic_flag flag = ATOMIC_FLAG_INIT;
public:
inline void lock() {
while (flag.test_and_set(std::memory_order_acquire))
;
}
inline void unlock() {
flag.clear(std::memory_order_release); }
};
template <typename T>
class TQueue {
public:
TQueue(int max = 64) : maxsz(max) {
}
void clear() {
std::lock_guard<SpinLock> lk(lock);
while (!que.empty()) {
que.pop();
}
}
T* pop() {
std::lock_guard<SpinLock> lk(lock);
if (que.empty()) {
return nullptr;
}
T* item = que.front();
que.pop();
return item;
}
bool push(T* item) {
std::lock_guard<SpinLock> lk(lock);
if (maxsz > 0 && maxsz > que.size()) {
que.push(item);
return true;
}
return false;
}
bool empty() const {
std::lock_guard<SpinLock> lk(lock);
return que.empty();
}
int size() const {
std::lock_guard<SpinLock> lk(lock);
return que.size();
}
private:
mutable SpinLock lock;
std::queue<T*> que;
int maxsz;
};