我有一个整数数组,用于跟踪 10,000 个并发任务的完成情况,其中值为 1 或 0。我认为如果这个数组是一个位数组并且每个并发线程使用 interlocked.CompareExchange(或类似的) 改变一个位。
如果 Interlocked 没有“位”过载,我应该如何处理?
我有一个整数数组,用于跟踪 10,000 个并发任务的完成情况,其中值为 1 或 0。我认为如果这个数组是一个位数组并且每个并发线程使用 interlocked.CompareExchange(或类似的) 改变一个位。
如果 Interlocked 没有“位”过载,我应该如何处理?
你可以在一个循环中伪造它Interlocked.CompareExchange(ref int, int, int)
,但我认为它不会更有效:
private static void SetBit(ref int valueToUpdate, int bitToSet)
{
while (true)
{
int oldValue = valueToUpdate;
int newValue = oldValue | bitToSet;
int result = Interlocked.CompareExchange(ref valueToUpdate, newValue, oldValue);
if (result == oldValue) break;
}
}
我不认为您可以使用Interlocked
. 我相信你必须切换到一个数组ints
,以便每一位都在它自己的int
.
Interlocked.CompareExchange
仅比较相等性,而您只需要比较一个位,除非您使用其他一些并发策略来保护该位所在的int
其他更改,否则您无法做到这一点。int
您需要线程安全的构造来跟踪并发任务的完成情况。因此,互锁结构总是比锁快(因为它们不需要锁),您应该Interlocked
使用带有整数的 -class 中的静态方法(例如,0 等效于false
1 true
,例如 1)。
Jeffrey Richter 所做的与他在他的书“CLR via C#”第 28 章“原始线程同步构造”中所描述的相同。他还在他的 Wintellect.PowerThreading 库中介绍了基于 Interlocked 构造的自己的锁实现,并对他自己的实现和 .net 框架中包含的实现进行了出色的解释和时间比较。
首先,不,所有互锁功能都在内存地址上工作,并且个别位不可寻址。
那么该怎么做呢?
我会调查两个选项:
InterlockedIncrement
每次任务完成时都会用到它。要查看是否所有任务都已完成,只需检查该值是否已达到 10,000。我不知道哪个最快。如果性能很重要,请对其进行基准测试。:)