由系统决定在多个线程中运行一个方法
本文关键字:方法 一个 运行 线程 决定 系统 | 更新日期: 2023-09-27 18:19:05
我有一个方法在两个列表中处理单词,一个优先级列表和一个标准列表。
ConcurrentBag<Word> PriorityWords = ...;
ConcurrentBag<Word> UnprocessedWords = ...;
public void ProcessAllWords()
{
while (true)
{
Word word = SelectWordToProcess();
if (word == null) break;
ProcessWord(word);
}
}
private Word SelectWordToProcess()
{
Word word;
if (PriorityWords.TryTake(out word) || UnprocessedWords.TryTake(out word))
return word;
else
return null;
}
public void ProcessWord(Word word) { ... }
我想在多个核上运行这个方法。目前,我只是为每个处理器打开一个线程:
for (int i = 0; i < Environment.ProcessorCount; i++)
{
new Thread(ProcessAllWords).Start();
}
是否有一种更合适的方法,让系统根据当前系统性能决定打开多少线程,类似于Parallel.ForEach()
?
EDIT:更多关于应用程序的细节。
单词列表预填充了~180,000个单词,每个单词都要与其他单词进行排列。ProcessAllWords
是一个O(n²)的操作。所有线程都将全速运行,直到处理完所有单词,然后终止。当线程运行时,我可以通过将特定单词添加到PriorityWords
列表中来异步地给予优先级。初始测试显示我的系统每秒处理大约5个单词,所以100%的CPU处理是10小时。
您启动环境的方法。ProcessorCount线程很好。任务并行库将执行您正在寻找的自动调度,但代价是过度订阅您的CPU。这将降低应用程序对优先级单词的响应性。
对于使用TPL的各种方法,并行for和任务工厂都将排队一堆单词,使其对优先级的响应非常迟钝。您可以使用生成器方法和PLINQ来维护您的优先级,但随后您将获得固定数量的线程,就像现在一样。您可以设置线程数,也可以使用默认的2xEnvironment.ProcessorCount。总而言之,由于您的任务是CPU限制的,我将保留您当前的实现。