我尝试在多线程环境中找到最佳相似性。
有没有更好的选择,或者两个版本在下面相同?
// float bestSimilarity is shared
// float _similarity is local
lock(locker)
if (_similarity > bestSimilarity)
bestSimilarity = _similarity;
VS
if (_similarity > bestSimilarity)
lock(locker)
bestSimilarity = _similarity;
答案 0 :(得分:7)
您的第一个案例将得到保证。然而,第二种情况可能会破裂。你比较,然后请求锁定,同时另一个线程已经修改bestSimilarity而你不知道它使比较无效。
如果您想在最后一刻避开锁定,可以进行两次比较。也就是说,比较,获取一个锁,再次进行比较,只有当它仍然有效时才增加该值。请注意使用您正在比较的值的本地缓存。如果你想这样做,你需要像MemoryBarrier一样进行某种同步。这一切都变得非常复杂,所以我建议只是锁定整个事情,除非你注意到性能确实是一个瓶颈
答案 1 :(得分:2)
共享bestSimilarity
时,您需要使用第一个代码段
答案 2 :(得分:1)
第二个不是线程安全的,另一个线程可以在执行if测试后更改_similarity
。
答案 3 :(得分:1)
第一个解决方案是线程安全的 - 第二个解决方案不是。 但是,您可以使用双重检查锁来减少获取锁的开销
if (_similarity > bestSimilarity)
{
lock(locker)
{
if (_similarity > bestSimilarity)
bestSimilarity = _similarity;
}
}
答案 4 :(得分:1)
你也可以无锁:
bool retry;
do
{
retry = false;
var copy = Interlocked.CompareExchange(ref bestSimilarity, 0, 0);
if (_similarity > copy)
{
retry = Interlocked.CompareExchange(
ref bestSimilarity, _similarity, copy) != copy;
}
} while (retry);
此:
bestSimilarity
的快照(我假设是累加器)_similarity
)与快照(稳定,作为本地)进行比较这是完全线程安全的,无锁的