Код: Выделить всё
#include
#include
#include
#include
#include
#define QUEUE_SIZE 20
std::atomic head {0};
std::atomic tail {0};
// Use an array of int pointers for storage
std::atomic data[QUEUE_SIZE] = {};
bool enqueue(int value) {
u_int current_tail = 0, next_tail = 0;
do {
current_tail = tail.load(std::memory_order_seq_cst);
next_tail = (current_tail + 1) % QUEUE_SIZE;
if (next_tail == head.load(std::memory_order_seq_cst)) {
return false; // queue is full
}
} while (!tail.compare_exchange_weak(current_tail, next_tail));
// Allocate memory for the value
int* new_value = new int(value);
// Attempt to store the value in the current tail slot
data[current_tail].store(new_value, std::memory_order_seq_cst);
return true;
}
int dequeue(int &value) {
u_int current_head = head.load(std::memory_order_seq_cst);
if (current_head == tail.load(std::memory_order_seq_cst)) {
return -1; // queue is empty
}
int* stored_value = data[current_head].exchange(nullptr, std::memory_order_seq_cst);
if (stored_value == nullptr) {
return -2; // not ready
}
value = *stored_value;
delete stored_value; // Free the allocated memory
u_int next_head = (current_head + 1) % QUEUE_SIZE;
head.store(next_head, std::memory_order_seq_cst);
return 0;
}
#define TEST_SIZE 50
#define NUMBER_OF_PRODUCERS 4
bool test_mpsc_queue() {
bool passed = true;
std::vector producers;
for (int producer_index = 0; producer_index < NUMBER_OF_PRODUCERS; producer_index++) {
producers.emplace_back([producer_index]() {
for (int i = 0; i < TEST_SIZE; i++) {
auto start_time = std::chrono::steady_clock::now();
auto end_time = start_time + std::chrono::seconds(10);
while (!enqueue(producer_index * TEST_SIZE + i)) {
// std::this_thread::yield();
if (std::chrono::steady_clock::now() > end_time) {
std::cout
Подробнее здесь: [url]https://stackoverflow.com/questions/79714059/this-mpsc-queue-multi-producer-single-consumer-queue-keeps-on-waiting-in-the-c[/url]