【发布时间】:2016-07-19 20:13:09
【问题描述】:
我尝试用 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”字符串之后是否可以完全访问?
【问题讨论】:
-
chunk.data 在 DONE 之后应该可以访问,只要函数还没有返回。但是,一旦函数返回,堆栈上的静态数组将无效,并且其中的任何切片也都指向垃圾。