【发布时间】:2017-05-01 09:02:28
【问题描述】:
我有一个名为updateEntry 的函数,它将一个值写入查找表。我想创建这个函数的多线程版本。
我正在研究原子操作__sync_bool_compare_and_swap,但我不确定如何在此处正确应用它。
理论上是否可以在不锁定的情况下自动实现此功能,因为它会更改两个独立的内存位置entryLookup[id] 和entry?
void updateEntry(Entry ** entryLookup, unsigned int id, int val1, short val2){
Entry * entry = entryLookup[id];
entry->val1 = val1;
entry->val2 = val2;
entryLookup[id] += sizeof(Entry);
}
【问题讨论】:
-
问题:1) 你能确保每个线程都能访问不相交的
id集合吗? 2) 你能保证修改val1和val2不会影响entryLookupoperator[]结果吗? 3) 你能确保修改entryLookup的值不会影响任何并行线程(例如,新的id 不会被任何其他线程访问)?如果其中任何一条规则不匹配,我认为实现无锁并发会很困难。 -
@AdrianMaire 非常感谢您的回答。我构建了一个使用不相交 id 集的解决方案,但生成这种不相交集的成本很高。我想避免使用不相交的 ID 集。第 2 点是什么意思。)?
-
Q4 - 更新是否与查找同步?如果没有,您可以首先自动更新
entryLookup[id],确保没有其他线程会使用相同的条目,然后在您闲暇时更新值(有点)。如果还要进行查找,则必须同时更新两个单独的位置,而这不能使用原始原子操作来完成。 -
定义“无锁定”——你总是可以使用原子的“正在更新”标志
-
我不知道
entryLookup是什么样子:我可以想象一个类,其中operator[]被重载并访问val1。想象一个第一个线程,访问 id=5,它返回 0x42 处的条目,在修改 val1 之后,entryLookup 现在对应于(例如)id=10。下一个线程访问 id=10 也对应于 0x42 处的条目。现在两个线程在没有锁的情况下同时访问同一个对象。
标签: c++ atomic lock-free compare-and-swap