3

我有两个线程共享一个循环队列。队列的内容是无符号数字(unsigned long在 x86_64 上)。一个线程是生产者,另一个是消费者。如果队列中元素的值为 0,则生产者仅写入队列中的元素,并且生产者始终产生非零值,而消费者仅在其值为非零时才使用它。此外,消费者在消费时将元素重置为 0,以便生产者知道消费者已经消费了它。

现在我的想法是,由于使用这种方案,队列中的元素有严格的访问顺序,我们不需要使用同步或原子变量。我的假设正确吗?或者我在这里遗漏了什么?请记住,x86_64 具有相对严格的一致性内存模型,并且只能将不相关的加载放在存储之前。它还具有缓存一致性,可以主动更新缓存。我还使用volatile变量来确保编译器不会缓存它们。

4

3 回答 3

3

是的,您需要同步,因为如果消费者赶上了生产者,生产者和消费者可能会同时尝试从同一位置读取和/或写入,反之亦然

即使您的处理器对您正在使用的数据类型执行原子操作,您通常也需要显式请求原子操作(通过适当的 API)以获得适当的内存屏障并确保即使您的线程在不同的内核上运行也能保持一致性。

于 2012-04-22T09:39:09.863 回答
2

我认为您不需要同步或原子变量。

一个生产者和一个消费者的两个线程不会与写入相同的条目发生冲突。

因为如果您的循环队列实现是正确的(例如,一个读取头变量,一个写入标签变量),这两个线程就不能在同一位置运行。无需限制条目结构。

阅读后似乎不需要重置条目。因为你应该移动你的读取头,生产者线程可以通过比较读取头变量和写入标签变量来知道是否可以写入一个条目。

可能对你有帮助:)

于 2012-04-22T09:42:47.613 回答
0

如果生产者和消费者只访问一个变量,您似乎不需要同步。但是既然你说你使用循环缓冲区,你就使用索引。如果不同步,索引变量很容易受到攻击。

于 2012-04-22T09:45:51.430 回答