Parallel.For最大线程和当前线程C#

时间:2014-01-27 16:45:07

标签: c# multithreading parallel-processing parallel.foreach

我想要实现的目标:

使用Parallel.For(其他任何内容都会受到赞赏,但发现这个是最简单的)我想增加一个名为max的变量,以便它到达100,000,000,使用线程,但程序应该同时只使用X个线程。

代码段:

using System;
using System.Threading;
using System.Linq;
using System.Threading.Tasks;

using System.Diagnostics;

namespace pool_threading
{
    class MainClass
    {
        static int max=0;
            static int current_max_thread=0;
        public static void Main (string[] args)
        {

            Parallel.For(0, 100000000, new ParallelOptions { MaxDegreeOfParallelism = 50 },
            i =>
            {
                            max++;
                if(Thread.CurrentThread.ManagedThreadId>current_max_thread)
                               current_max_thread=Thread.CurrentThread.ManagedThreadId;
            });

            Console.WriteLine ("I got to this number {0} using most {1} threads",max,current_max_tread);
        }
        public static void GetPage(int i)
        {
        }

    }
}

结果:

我使用最多11个帖子

得到了这个号码38,786,886

现在......我不知道为什么我得到的数字38,786,886小于38,786,886,但我想这是因为多个线程试图在同一时间增加它,所以,如果10个人同时尝试,只有第一个人有机会。如果我错了,请纠正我。

最大的“问题”是我一直得到11个线程,即使最大值设置为50(滚动代码看最大值),如果我将它设置为最大1个线程,我总是得到4个(也许4是这种情况下的最小值,但它仍然无法解释为什么我同时只获得最大值11。)

3 个答案:

答案 0 :(得分:2)

这很简单,只需在循环内部使用i,而不是尝试增加并使用max。你没有安全地增加它,但你没有理由去尝试。 Parallel.For的整个是它给你循环索引,并确保每个循环索引只被命中一次,不多也不少。

答案 1 :(得分:1)

据我所知,这里有两件事:

首先,你正在从多个线程中瞄准max。你可能有一台多核机器。这些操作可能彼此重叠。要以线程安全的方式执行递增,需要

   Interlocked.Increment(ref max);

   max++;   /* not thread safe */

其次,您并不总是获得MaxDegreeOfParallelism中要求的线程数。你永远不会得到更多,但你可能会得到更少。

如果您要使用并行性,请密切注意您将在线程中运行的代码的线程安全性。

答案 2 :(得分:0)

我认为你有两个主要原因没有获得50个帖子:

  1. 硬件。有一个点,处理器可以用更少的线程做更多的事情,因为切换线程所花费的时间不仅仅是更频繁地运行线程。这导致

  2. 托管代码。 C#.NET是一个托管代码系统。 .Net的程序员知道上面的内容,可能会设置一些限制和检查以防止太多的线程运行。您在代码中设置的内容可能高于某个内部限制,因此实际上会被忽略。此外,您正在设置最大值,因此Parallel.For()可以使用1到X个线程的任何位置,无论它认为哪个最有效。