【问题标题】:C# parallel and multithreading on single core cpu单核 cpu 上的 C# 并行和多线程
【发布时间】:2015-03-28 14:24:30
【问题描述】:

我有一个使用 C# 和 .net 4.5 的应用程序,可以在 Windows 8.1 的 Intel Core i5 系统上运行,但是当我发布应用程序并安装在 Windows 7 SP1 上时,该应用程序在 Intel Pentium 4 单核和单线程系统上运行.net 4.5.3 应用程序无法完全运行。 我猜想导致这个问题的代码部分使用了Parallel.Foreach

我的应用程序也使用异步等待。

Parallel.Foreach 和 async await 真的只能在多线程处理器上工作吗?

如何在单核上使用这个程序?如果需要替换代码我应该使用什么?

【问题讨论】:

  • 当你说它不能“完全”工作时,你是什么意思?
  • 并行处理(或并行编程)使用多线程来最大限度地利用多个处理器。更多讨论请参见safaribooksonline.com/library/view/concurrency-in-c/…
  • @Moo-Juice,程序启动没有错误,一些OpenFileDialog,Buttons和其他功能可以工作,但是当使用parallel.foreach时它没有进入下一步,UI没有冻结。
  • @David,这是否意味着并行编程不适用于单线程处理器?
  • @Execute.H - 不,不是那个意思。这意味着您正在做一些在单个 CPU 架构中表现不同的事情。这很可能是某种死锁。但是,由于您没有包含任何显示问题的源代码,我们无法提供帮助。

标签: c# .net multithreading parallel-processing


【解决方案1】:

Parallel.Foreach 使用的 TPL 使用线程而不是内核,由操作系统来调度这些线程。单核处理器将简单地通过单核运行与 Parallel.Foreach 代码关联的线程,而不会出现问题。另一方面,异步/等待方法不会显式创建额外的线程,而是在当前同步上下文上运行,并且仅在方法处于活动状态时才在线程上使用时间。同样,单核 CPU 应该毫无问题地处理 async/await。

话虽如此,由于与线程创建/管理相关的额外开销,使用 Parallel.Foreach 实际上可能会降低性能。如果代码不受 CPU 限制,Parallel.Foreach 并不是最好的方法。

【讨论】:

  • 谢谢,我该如何诊断这个问题?我对此一无所知,该应用程序在我的笔记本电脑上运行并正常运行,但在我朋友的 PC 上却无法运行。
  • 当您尝试在您朋友的 PC 上运行该应用程序时会发生什么?您是否在应用程序中设置了任何错误日志记录?你检查过 PC 上的事件查看器吗?
  • 会不会是部署问题?我同时使用了 VS 发布和 Visual Studio 安装程序(安装项目)。
  • 您在什么操作系统上运行应用程序?机器上安装了哪些版本的 .NET 框架?
  • 同意您所说的所有内容,除了“如果代码不受 CPU 限制,Parallel.Foreach 并不是最好的方法。如果代码不受 CPU 限制,Parallel.Foreach 并不是最好的方法。”。当获取 URL 等任务花费的时间太长时,您可以将其分配给单独的线程并使用 CPU 执行更高效的操作。
【解决方案2】:

@JTW 的回答很好,我还要添加以下内容:

  • 如果系统只有一个处理器,将程序转换为使用多线程实现不会提高处理数据的速度。这是在 CPU 受限 程序的情况下。例如。特定数据集的数值分析。此外,程序不会抛出异常。

  • 但是,考虑一个不断与文件系统交互的程序。此应用程序是IO(输入/输出)绑定,因为它可以工作的速率取决于文件系统的性能。多线程解决方案将能够在一个任务正在等待输入/输出操作完成时执行处理。

PS。我知道我迟到一年才加入这个话题,但希望它对某人有所帮助。

【讨论】:

    【解决方案3】:

    我希望我不会因为挖掘这个而受到抨击,但我只是在学习 Parallel.ForEach 并想知道它在单核机器上的表现。

    对于将来可能还会研究此问题的任何人,我会说尝试使用 ParallelOptions 类的 MaxDegreeOfParallelism 属性,该属性可以像这样传递给 ForEach 方法:

    void DoSomethingParallel()
    {
        ParallelOptions parOpts = new ParallelOptions();
        parOpts.MaxDegreeOfParallelism = System.Environment.ProcessorCount;
    
        object[] objs = new object[10];
    
        Parallel.ForEach(objs, parOpts, currObj =>
        {
            Console.WriteLine("This is the current object: {0}", currObj.ToString());
        });
    }
    

    抱歉,如果这不能解决问题。我还没试过。

    【讨论】:

    • 你应该查一下,我认为这是默认的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 2014-02-20
    • 2016-08-10
    • 1970-01-01
    • 2011-04-03
    相关资源
    最近更新 更多