linux 内核 多生产者 多消费者 不使用原子变量 无锁 队列 实现示例代码。
以下是一个使用无锁队列实现多生产者多消费者的示例代码:
#include <iostream>
#include <thread>
#include <atomic>
template <typename T>
class LockFreeQueue {
public:
LockFreeQueue() {
Node* node = new Node();
tail_ = head_ = node;
}
~LockFreeQueue() {
T value;
while (dequeue(value)) {}
delete head_;
}
void enqueue(const T& value) {
Node* node = new Node(value);
Node* tail = tail_.load();
while (true) {
Node* next = tail->next.load();
if (next == nullptr) {
if (tail->next.compare_exchange_strong(next, node)) {
tail_.compare_exchange_strong(tail, node);
return;
}
} else {
tail_.compare_exchange_strong(tail, next);
}
}
}
bool dequeue(T& value) {
Node* head = head_.load();
while (true) {
Node* tail = tail_.load();
Node* next = head->next.load();
if (head == tail) {
if (next == nullptr) {
return false;
}
tail_.compare_exchange_strong(tail, next);
} else {
if (head_.compare_exchange_strong(head, next)) {
value = next->value;
delete head;
return true;
}
}
}
}
private:
struct Node {
T value;
std::atomic<Node*> next;
Node() : next(nullptr) {}
Node(const T& value) : value(value), next(nullptr) {}
};
std::atomic<Node*> head_;
std::atomic<Node*> tail_;
};
LockFreeQueue<int> queue;
void producer(int id) {
for (int i = 0; i < 10; ++i) {
int value = id * 10 + i;
queue.enqueue(value);
std::cout << "Producer " << id << " enqueued " << value << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void consumer(int id) {
int value;
while (true) {
if (queue.dequeue(value)) {
std::cout << "Consumer " << id << " dequeued " << value << std::endl;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
int main() {
std::thread p1(producer, 1);
std::thread p2(producer, 2);
std::thread c1(consumer, 1);
std::thread c2(consumer, 2);
p1.join();
p2.join();
c1.join();
c2.join();
return 0;
}
该示例代码中使用了一个模板类 LockFreeQueue 表示无锁队列,其中包含一个内部类 Node 表示队列中的节点,节点中包含了一个值和一个指向下一个节点的原子指针。
生产者线程通过调用 enqueue 方法将值插入队列中,消费者线程通过调用 dequeue 方法从队列中取出值。在无锁队列的实现中,每个节点的 next 指针都是原子的,因此能够保证多线程并发访问时不会出现冲突。同时,通过使用 CAS 操作,能够保证在多线程并发访问时不会出现竞态条件,因此无需使用锁来保护队列的操作
原文地址: https://www.cveoy.top/t/topic/e8uE 著作权归作者所有。请勿转载和采集!