使用atomic_flag来控制原子性
while (flag.test_and_set(std::memory_order_acquire)); 做加锁
flag.clear(std::memory_order_release); 做解锁
这里涉及到了内存序的问题,后面再讲。
队列采用std::queue,然后装饰器模式一下,用模板泛型实现,相应的
- clear
- pop
- push
- size
- empty
队列长度可设置,默认是64
代码如下
#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;
};