gpt4 book ai didi

d - 无锁固定大小队列失败

转载 作者:行者123 更新时间:2023-12-02 01:27:22 25 4
gpt4 key购买 nike

我尝试用D语言实现类似无锁固定大小队列的东西

import core.atomic;
struct Chunk(T, uint N)
{
T[N] data;
shared uint count_;
shared uint queueCounter;

@property bool full() { return count_ == N; }

void append(T value)
{
atomicOp!("+=")(queueCounter, 1);
while(1)
{
uint c = count_;
if(cas(&count_, c, c + 1))
{
data[c] = value;
atomicOp!("-=")(queueCounter, 1);
break;
}
}
}

bool wait()
{
if(!full())
{
return false;
}

while(0 != queueCounter) {}

return true;
}
}

这样调用它:

import std.parallelism;

struct S
{
bool dirty;
int time;
int[16] data;
}

int main(string[] argv)
{
const uint N = 14343;

Chunk!(S, N) ch;


foreach(i; taskPool.parallel(std.range.iota(N), 10))
{
S item;
item.time = i;
ch.append(item);
}
while(!ch.wait()) {}

// DONE

return 0;
}

它在 N == 14343 下工作正常,但在 14344 下没有任何消息(值取决于 S.sizeof)失败。

为什么程序会失败?

我的 CAS 追加是否正确?

chunk.data 在“DONE”字符串之后是否完全可访问?

最佳答案

看起来您正在 Windows 上运行它,默认堆栈大小为 1 MB(至少根据 this article at MSDN )。

您的 S.sizeof 可能是 72,它给出的 S 实例不超过 14563 个(堆栈上还有其他东西,因此您的最大 N略低)。

在堆栈上放置一个较大的变量会导致堆栈溢出,这应该在调用 main 时立即发生:ch 然后被赋予 Chunk!(S, N) 的值。 init 会导致堆栈边界外的写入,命中保护页并因此导致程序因段错误而崩溃(至少这是 Linux 上的结果,当 N 大到足以溢出默认 8 兆字节堆栈),或者用 Windows 术语来说,访问冲突(我现在没有 Windows 机器来验证它)。

有几种解决方法:

  1. 使用较小的N
  2. 增加堆栈大小(参见上面链接的文章)。
  3. 在堆上分配数据

关于d - 无锁固定大小队列失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36332310/

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