ThreadLocal <t>在特定条件下不断增长

时间:2017-02-26 11:30:05

标签: c# .net multithreading threadpool parallel.foreach

我正在为一定数量的迭代运行模拟。在每次迭代结果发送后,服务器和一段时间之后服务器发送在下一次迭代中使用的更新数据。

代码(非常粗略地)看起来像这样:

for(var iteration=0;iteration<100;iteration++)
{
 Parallel.For(0,50,i=>DoExpensiveWork(i));
 SendResultsToServer(); //worker sends iteration results to server

 //server gathers results from all workers, 
 //calculates update, then sends it back to workers
 WaitForDataForNextIteration(); 
}

DoExpensiveWork正在使用ThreadLocal缓存(大多数只是每次迭代都重用的大型数组,以避免GC工作)。

ThreadLocal<MyCache> _cache;

private void DoExpensiveWork(int i)
{
   var cache = _cache.Value;
   DoSomeWorkUsingCache(cache);
}

以下是我遇到的问题:

  1. 随着时间的推移,_cache增长缓慢(即_cache.Values.Count)增加的值远高于我机器上的核心数量(我猜这意味着旧线程有时会被{{1下一次迭代使用新创建的线程,导致在ThreadPool中创建其他条目。 这会导致“内存泄漏”。因为旧的缓存仍然保留在内存中,而无法访问。

  2. 当服务器花费大量时间发送更新时,_cache.Values会在每次迭代时增长(在32核心机器上(2x16)_cache增长如32,64,96等 - 增加32个新每次迭代的条目)。这只发生在服务器发送更新大约需要20秒时(如果需要15秒或更短时间,则不会发生这种情况)。 当工人等待更新时,这是否意味着_cache.Values正在破坏线程?

  3. 我该怎样防止这种情况? 将最小/最大线程数设置为32无效

    ThreadPool

    我想要的主要是停止ThreadPool.SetMinThreads(32,1000); ThreadPool.SetMaxThreads(32,1000); 缓存创建新条目,因此在我的情况下它不会超过32。

    编辑:来自MSDN:当需求低时,线程池线程的实际数量可能会低于最小值。这可以解释为什么越来越多{{i> 1}}副本已创建。对此有何解决方法?

0 个答案:

没有答案