- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在无锁的多生产者多消费者环形缓冲区上猛烈抨击(我的尝试)。这个想法的基础是使用无符号字符型和无符号短类型的先天溢出,将元素缓冲区固定为这些类型中的任何一个,然后您可以自由循环回到环形缓冲区的开头。
问题是-我的解决方案不适用于多个生产者(尽管适用于N个消费者,也适用于单个生产者单个消费者)。
#include <atomic>
template<typename Element, typename Index = unsigned char> struct RingBuffer
{
std::atomic<Index> readIndex;
std::atomic<Index> writeIndex;
std::atomic<Index> scratchIndex;
Element elements[1 << (sizeof(Index) * 8)];
RingBuffer() :
readIndex(0),
writeIndex(0),
scratchIndex(0)
{
;
}
bool push(const Element & element)
{
while(true)
{
const Index currentReadIndex = readIndex.load();
Index currentWriteIndex = writeIndex.load();
const Index nextWriteIndex = currentWriteIndex + 1;
if(nextWriteIndex == currentReadIndex)
{
return false;
}
if(scratchIndex.compare_exchange_strong(
currentWriteIndex, nextWriteIndex))
{
elements[currentWriteIndex] = element;
writeIndex = nextWriteIndex;
return true;
}
}
}
bool pop(Element & element)
{
Index currentReadIndex = readIndex.load();
while(true)
{
const Index currentWriteIndex = writeIndex.load();
const Index nextReadIndex = currentReadIndex + 1;
if(currentReadIndex == currentWriteIndex)
{
return false;
}
element = elements[currentReadIndex];
if(readIndex.compare_exchange_strong(
currentReadIndex, nextReadIndex))
{
return true;
}
}
}
};
最佳答案
这是A-B-A problem的一种形式。一个成功的制作人看起来像这样:
currentReadIndex
currentWriteIndex
scratchIndex = nextWriteIndex
element
writeIndex = nextWriteIndex
scratchIndex
来锁定队列,即使检测到ABA的神奇cmpxchg拒绝了商店,生产者也将再次尝试,重新加载完全相同的
currentWriteIndex
并正常进行。
nextWriteIndex == currentReadIndex
检查。如果是
currentReadIndex == currentWriteIndex
,则队列在逻辑上是空的,因此存在此检查是为了确保没有任何生产者超前以至于它覆盖了尚未弹出任何使用者的元素。在顶部进行一次此检查似乎是安全的,因为所有使用者都应“困在”所观察到的
currentReadIndex
和所观察到的
currentWriteIndex
之间。
writeIndex
之外,这使消费者摆脱了陷阱。如果生产者在第2步和第3步之间停顿,当它唤醒时,
readIndex
的存储值可能是绝对任何值。
writeIndex = 1
,现在两个存储的索引均为1,并且队列在逻辑上为空。现在,将完全忽略队列中所有元素的值(value)。 scratchIndex
保护并发写入的方式本质上是一种锁定。成功完成cmpxchg的任何人都将获得对该队列的总写访问权限,直到释放该锁为止。解决此故障的最简单方法是仅用自旋锁替换
scratchIndex
-它不会遭受A-B-A的折磨,而这实际上正在发生。
关于multithreading - 无锁有界MPMC环形缓冲区故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25016001/
我正在尝试从网站(名称)“抓取”一些数据。我知道如何获得列表中的第一个名字——但我需要以同样的方式保存几千个名字。 这是我的代码: library(rvest) library(tidyverse)
我正在尝试制作一个环形 UIBezierPath 用作 CAShapeLayer 的 path 以下产生一个循环路径: let radius = 100.0 let circularPath = UI
如何在 1 分钟后停止 setTimeout。由于循环,它继续运行。TIA var image1 = new Image() image1.src = "images/slide1.jpg"
我现在这个问题发布了更多次,但我还没有解决我的问题。在我的例子中,foregroundColor 不工作。即使 foregroundColor 没有选择任何颜色,环也不会出现 darkGray 颜色。
public class Tester { // instance variables - replace the example below with your own Scanne
来自澳大利亚的投票问题: 一个机器人会不断地输入信息,它可以达到 1000 行。他将输入的内容示例: "1 2 3 2 1 3 2 3 1 1 2 3 3 1 2 " 我怎么知道他什么时候输入完信息?
有人可以启发如何进行这项工作吗?所以现在我有一个 do/while 循环,里面有一个开关。开关由一个 int 选择处理,scanf 是“%d”。但是,如果我写一个不同于数字的字符符号,如 a、b、c.
我是一名优秀的程序员,十分优秀!