我只想计算每个并行线程的数量。
我刚刚写了这段代码,并期待线程。计数等于threadsCount是相同的,但它不是。变量threadsCount总是大于threads.Count。为什么?
还有,为什么我应该使用Interlocked而不是像HashSet这样的标准集合?
int threadsCount = 0;
HashSet<int> threads = new HashSet<int>();
Parallel.ForEach(productConfig.Documenti.Keys, new ParallelOptions { MaxDegreeOfParallelism = MaxNumOfThreads }, key =>
{
int progress = Interlocked.Increment(ref threadsCount);
threads.Add(System.Threading.Thread.CurrentThread.ManagedThreadId);
});
1条答案
按热度按时间cyej8jka1#
你的联锁计数器是在计算键,而不是线程。回调将在每个 * 键 * 上调用,这些回调将在它 * 选择 * 使用的任何数量的线程之间传播,最多
MaxDegreeOfParallelism
。它 * 不是 * 每个键一个线程-因为线程非常昂贵,而且通常没有多少点并行化线程比你有CPU内核。通常,它只是在一定数量的池线程之间分担负载。所以,是的,我们希望您的互锁计数器最终与productConfig.Documenti.Keys.Count
具有相同的数字,并且threads.Count
最终是 * 实际使用的线程数量 *。我们希望threads.Count
通常比您的计数器小得多,除非只有一个或两个密钥。注意:
HashSet<T>
不是线程安全的,所以现在这段代码可能会崩溃--你需要使用并发或同步的数据存储来使它可靠地工作。还有,为什么我应该使用Interlocked而不是像HashSet这样的标准集合?
为什么要使用这两种方法中的任何一种?为什么要关心使用了多少线程?为什么要计算 * 您自己提供的 * 密钥?