安全地限制并行,Foreach 循环中的类调用数量
本文关键字:调用 循环 Foreach 并行 安全 | 更新日期: 2023-09-27 18:30:44
我有一个简单的foreach循环,它基于while循环和静态int来限制自己。 如果我不限制它,如果我限制它,我的 CPU 将保持在 10% 以下,我的 CPU 将上升到 99/100%。 如何安全地限制对 Paralell.Foreach 中类的调用次数?
static int ActiveThreads { get; set; }
static int TotalThreads { get; set; }
var options = new ParallelOptions();
options.MaxDegreeOfParallelism = 1;
Parallel.ForEach(urlTable.AsEnumerable(),options,drow =>
{
using (var WCC = new MasterCrawlerClass())
{
while (TotalThreads <= urlTable.Rows.Count)
{
if (ActiveThreads <= 9)
{
Console.WriteLine("Active Thread #: " + ActiveThreads);
ActiveThreads++;
WCC.MasterCrawlBegin(drow);
TotalThreads++;
Console.WriteLine("Done Crawling a datarow");
ActiveThreads--;
}
}
}
});
我需要限制它,是的,我知道最大并行性有自己的限制,但是,在服务器中的 CPU 达到该限制之前,我的交换机陷入困境。
两件事:
1) 您似乎没有使用在此示例中创建的ParallelOptions()
。
2)如果由于某种原因您不想使用ParallelOptions
,则可以使用Semaphore
。
Semaphore sm = new Semaphore(0, 9);
// increment semaphore or block if = 9
// this will block gracefully without constantly checking for `ActiveThreads <= 9`
sm.WaitOne();
// decrement semaphore
sm.Release();
我有一个简单的 foreach 循环,它根据 while 循环限制自己 和一个静态整数。如果我不限制它,我的 CPU 保持在 10% 以下,如果我 限制它,我的CPU上升到99/100%。
这很奇怪。这可能是由于您限制循环的并发性的方式,顺便说一下,这似乎会导致每个drow
被多次爬网。我怀疑这就是你想要的。由于爬网操作受 IO 限制,因此 CPU 利用率较低。
如果您确实要将并发呼叫数限制为 MasterCrawlBegin
个,请设置 MaxDegreesOfParallelism = 9
。TotalThreads
和ActiveThreads
的while
循环和维护是行不通的。作为旁注,您正在以非线程安全的方式递增和递减计数器。
将代码更改为如下所示。
int ActiveThreads = 0;
var options = new ParallelOptions();
options.MaxDegreeOfParallelism = 9;
Parallel.ForEach(urlTable.AsEnumerable(),options,drow =>
{
int x = Interlocked.Increment(ref ActiveThreads);
Console.WriteLine("Active Thread #: " + x);
try
{
using (var WCC = new MasterCrawlerClass())
{
WCC.MasterCrawlBegin(drow);
}
}
finally
{
Interlocked.Decrement(ref ActiveThreads);
Console.WriteLine("Done Crawling a datarow");
}
});