0

我有一种方法可以处理两个列表中的单词,一个优先级列表和一个标准列表。

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()


编辑:有关应用程序的更多详细信息。

单词列表预先填充了大约 180,000 个单词,并且每个单词都将与其他单词进行排列。 ProcessAllWords是一个 O(n²) 操作。线程将全部运行,直到处理完所有单词,然后终止。当线程正在运行时,我可以通过将特定单词添加到PriorityWords列表中来异步赋予它们优先级。初步测试显示我的系统处理速度约为 5 个字/秒,因此 100% 的 CPU 处理时间为 10 小时。

4

1 回答 1

1

您启动 Environment.ProcessorCount 线程的方法很好。任务并行库将执行您正在寻找的自动调度,但代价是过度订阅您的 CPU。这将降低您的应用程序对优先词的响应能力。

至于使用 TPL 的各种方法,parallel for 和 task factory 都会排队一堆字,对优先级很不敏感。您可以使用生成器方法和 PLINQ 来保持优先级,但随后您将获得固定数量的线程,就像现在一样。您可以设置线程数或使用默认值 2xEnvironment.ProcessorCount。总而言之,由于您的任务受 CPU 限制,我会保留您当前的实现。

于 2013-06-20T13:56:54.913 回答