gpt4 book ai didi

c - 无等待环形缓冲区

转载 作者:行者123 更新时间:2023-11-30 17:43:59 26 4
gpt4 key购买 nike

我有一个场景,我可以有多个生产者但有一个环形缓冲区的单个消费者。这是源代码:

typedef struct ring_buffer_t {
uint8_t *data;
uint32_t element_size;
uint32_t element_count;
uint32_t head;
uint32_t tail;
uint32_t mask;
} ring_buffer;

uint32_t ring_buffer_put(ring_buffer *buf, void *data_element) {
int i;
uint32_t status = 0;
uint8_t *buf_pointer;
uint8_t *element = (uint8_t *) data_element;

if (buf && data_element) {

buf_pointer = &buf->data[(buf->head & buf->mask) * buf->element_size];
for (i = 0; i < buf->element_size; ++i) {
buf_pointer[i] = element[i];
}

status = 1;
__sync_fetch_and_add(&buf->head, 1);

}

return status;
}

uint32_t ring_buffer_size(ring_buffer *buf) {

return buf->head - buf->tail;
}

uint32_t ring_buffer_empty(ring_buffer *buf) {

return (ring_buffer_size(buf) == 0);
}

void *ring_buffer_get(ring_buffer *buf) {
void *element;
//preserve the invariant that tail is always <= head
if (ring_buffer_empty(buf)) {
return 0;
}

element = &buf->data[(buf->tail & buf->mask) * buf->element_size];
__sync_fetch_and_add(&buf->tail, 1);
return element;
}

问题陈述允许我覆盖旧条目,例如这就是为什么我使用 and 并且在放置时不检查缓冲区是否已满 - 我只是覆盖最旧的条目。但是,我很难推理这是否是线程安全的。如前所述 - 重要的是,这是无等待的(根据定义分别是无锁的),因为生产者无法承受阻塞。大小始终是 2 的幂,这就是索引期间 & 起作用的原因。

任何意见都会受到赞赏?

最佳答案

不,您的实现不是线程安全的。

如果两个线程同时放入元素,它们最终可能会在同一位置写入,甚至在一个位置写入一半记录,在下一个位置写入另一半记录。

关于c - 无等待环形缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20145063/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com