由系统决定在多个线程中运行一个方法

本文关键字:方法 一个 运行 线程 决定 系统 | 更新日期: 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限制的,我将保留您当前的实现。