gpt4 book ai didi

c - 只阻塞消费者的单一生产者/消费者循环缓冲区

转载 作者:行者123 更新时间:2023-12-04 10:12:38 26 4
gpt4 key购买 nike

我想实现一个包含单个生产者和单个消费者的缓冲区,其中只有消费者可能被阻塞。这里的重要细节是,如果队列已满,生产者可以丢弃更新。

我考虑过转换一个无等待的实现,但乍一看似乎没有简单的方法来通知消费者新数据已经到达而不丢失通知。所以我选择了下面非常简单的方法,使用计数信号量(为清楚起见省略了一些错误处理细节):

Object ar[SIZE];
int head = 0, tail = 0;
sem_t semItems; // initialized to 0

void enqueue(Object o) {
int val;
sem_getvalue(&semItems, &val);
if (val < SIZE - 1) {
ar[head] = o;
head = (head + 1) % SIZE;
sem_post(&semItems);
}
else {
// dropped
}
}
Object dequeue(void) {
sem_wait(&semItems);
Object o = ar[tail];
tail = (tail + 1) % SIZE;
return o;
}

此代码是否存在任何安全问题?我很惊讶在流行文学中没有看到类似的实现。另一个问题是 sem_post() 是否会阻塞(在 linux 中调用 futex_wake())。当然也欢迎更简单的解决方案。

编辑:编辑代码以在读者和作者之间留出空间(参见 Mayurk 的回复)。

最佳答案

我可以看出这个实现中的一个问题。考虑以下顺序。

  1. 假设缓冲区已满,但消费者尚未启动。所以(头=0,尾=0,sem_val=SIZE)。
  2. dequeue() 从消费者线程调用。 sem_wait() 成功。所以就在那个实例 (head=0, tail=0, sem_val=SIZE-1)。消费者开始阅读 ar[0]。
  3. 现在有一个线程切换。 enqueue() 从生产者线程调用。 sem_getvalue() 将返回 SIZE-1。所以生产者写在 ar[0]。

基本上我认为您需要对读写操作进行互斥保护。但是添加互斥锁可能会阻塞线程。所以我不确定你是否从这个逻辑中得到了预期的行为。

关于c - 只阻塞消费者的单一生产者/消费者循环缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40757091/

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