【问题标题】:Parallel.For out-of-sync outputParallel.For 不同步输出
【发布时间】:2013-12-04 04:57:53
【问题描述】:

我对 C# 4.0 中的并行编程类有点陌生;正在尝试一个简单的 for 循环,我通常应该使用通常的 for 循环按顺序打印从 0 到 99 的长整数,但是使用 Parallel.For,我会以随机混乱的顺序得到不一致的输出。

代码:

using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            Parallel.For(0, 100, i =>
            {
                //object sync = new object(); 
                //lock (sync)
                {
                    Console.WriteLine("Writing" + i);
                }
            });
            Console.Read();
        }
    }
}

控制台上的一个输出:

Writing0
Writing1
Writing2
Writing3
Writing4
Writing5
Writing6
Writing7
Writing8
Writing9
Writing10
Writing11
Writing12
Writing13
Writing14
Writing15
Writing16
Writing17
Writing18
Writing19
Writing20
Writing21
Writing22
Writing23
Writing24
Writing25
Writing26
Writing27
Writing28
Writing29
Writing30
Writing31
Writing32
Writing33
Writing34
Writing35
Writing36
Writing37
Writing38
Writing39
Writing40
Writing41
Writing42
Writing43
Writing44
Writing45
Writing46
Writing47
Writing48
Writing49
Writing50
Writing66
Writing67
Writing68
Writing70
Writing71
Writing72
Writing73
Writing74
Writing75
Writing76
Writing77
Writing78
Writing69
Writing82
Writing83
Writing84
Writing85
Writing86
Writing87
Writing88
Writing89
Writing90
Writing51
Writing52
Writing53
Writing54
Writing55
Writing91
Writing92
Writing93
Writing94
Writing95
Writing56
Writing57
Writing79
Writing80
Writing81
Writing58
Writing59
Writing96
Writing97
Writing98
Writing99
Writing60
Writing61
Writing62
Writing63
Writing64
Writing65

在此先感谢你们,无论你们对我有什么帮助。

【问题讨论】:

  • 有些人在遇到问题时会想,“我知道,我会使用线程”,然后他们就有了两个问题。 twitter.com/nedbat/status/194452404794691584
  • Parralel foreach 不保证按顺序执行。我保证所有线程都会在继续之前完成。说真的,阅读一些文档。输出没有任何不一致的地方;事实上,与所有非同步线程一样,它始终不一致。
  • daveL - 您没有阅读我的问题的第一行。无论如何,谢谢。
  • 您希望输出是什么?您要求并行执行多个迭代,但也期望结果完全序列化(1,然后 2,然后 2,...)。这没有多大意义。
  • 你是对的。但是让它们以串行/同步方式(以某种方式)执行也常常是挑战。

标签: c# task-parallel-library


【解决方案1】:

这就是并行计算。任务排队,每个可用的处理器都有一个。如果完成,下一个排队的任务将发给它。没有保证将任务交付给处理单元的顺序,也没有保证下一个将完成的任务,因此可并行代码与顺序代码+关键字parallel不同。需要开发算法以能够并行运行。在您的简单示例中,写入了从 1 到 100 的所有数字,但并行循环不会按照您期望的自然顺序写入它们。

【讨论】:

    【解决方案2】:

    这是意料之中的,您在那里执行的方式是使用当前线程以及从线程池中提取的一些其他线程来划分工作。

    如果你想在不同的线程上做同样的事情,但让写入同步,那么你可以尝试:

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var t = Task.Factory.StartNew(() => { 
                    for(var i = 0;i<100;i++)
                    {
                        //object sync = new object(); 
                        //lock (sync)
                        {
                            Console.WriteLine("Writing" + i);
                        }
                    }
                });
                Console.Read();
            }
        }
    }
    

    【讨论】:

    • 这正是我想要的。这就是您编写利用并行计算/ TPL 优势的 for 循环的方式,但仅按照标准 for 循环的目标顺序执行?再次感谢您的帮助。
    • “每次迭代都会创建一个不同的线程”这将是非常低效的,这肯定不是Parallel.For 所做的。
    • 我更新了我的答案,使其更正确地了解该方法的工作原理。你是对的,它不是每次迭代的新线程(可能)。相反,它将迭代划分为当前线程以及从线程池中提取的其他几个线程。
    猜你喜欢
    • 1970-01-01
    • 2019-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    相关资源
    最近更新 更多