使用c++11实现无锁队列
时间: 2024-05-10 14:21:41 浏览: 105
以下是使用C11实现无锁队列的示例代码:
```c
#include <stdatomic.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
typedef struct {
uintmax_t capacity;
atomic_uintptr_t head;
atomic_uintptr_t tail;
void *entries[];
} queue_t;
queue_t *queue_create(uintmax_t capacity)
{
queue_t *q = malloc(sizeof(queue_t) + capacity * sizeof(void *));
if (q == NULL) {
return NULL;
}
q->capacity = capacity;
atomic_init(&q->head, (uintptr_t) q);
atomic_init(&q->tail, (uintptr_t) q);
return q;
}
void queue_destroy(queue_t *q)
{
free(q);
}
bool queue_push(queue_t *q, void *entry)
{
uintptr_t tail = atomic_load_explicit(&q->tail, memory_order_relaxed);
for (;;) {
queue_t *tail_ptr = (queue_t *) tail;
uintptr_t head = atomic_load_explicit(&q->head, memory_order_acquire);
if (tail_ptr == (queue_t *) atomic_load_explicit(&q->tail, memory_order_relaxed)) {
if (head == (uintptr_t) tail_ptr) {
if (atomic_compare_exchange_weak_explicit(&q->head, &head, (uintptr_t) tail_ptr->entries, memory_order_release, memory_order_acquire)) {
tail_ptr->entries[0] = entry;
atomic_store_explicit(&q->tail, (uintptr_t) (tail_ptr->entries + 1), memory_order_release);
return true;
}
} else {
uintptr_t tail_index = (uintptr_t) tail % q->capacity;
if (atomic_compare_exchange_weak_explicit(&q->tail, &tail, (uintptr_t) (tail_ptr->entries + ((tail_index + 1) % q->capacity)), memory_order_release, memory_order_relaxed)) {
tail_ptr->entries[tail_index] = entry;
return true;
}
}
}
}
}
bool queue_pop(queue_t *q, void **entry)
{
uintptr_t head = atomic_load_explicit(&q->head, memory_order_relaxed);
for (;;) {
queue_t *head_ptr = (queue_t *) head;
uintptr_t tail = atomic_load_explicit(&q->tail, memory_order_acquire);
if (head_ptr == (queue_t *) atomic_load_explicit(&q->head, memory_order_relaxed)) {
if (head_ptr == (queue_t *) tail) {
return false;
}
uintptr_t head_index = (uintptr_t) head % q->capacity;
*entry = head_ptr->entries[head_index];
if (atomic_compare_exchange_weak_explicit(&q->head, &head, (uintptr_t) (head_ptr->entries + ((head_index + 1) % q->capacity)), memory_order_release, memory_order_relaxed)) {
return true;
}
}
}
}
```
该实现使用两个原子指针来跟踪队列的头尾。在队列满时,使用一个额外的指针数组来存储条目。使用`memory_order_acquire`和`memory_order_release`来确保原子操作的顺序,以避免不正确的共享内存问题。
阅读全文