2009-08-03 43 views
2

我有一个Intel四核CPU。内核与我可以产生的线程数之间的关系

如果我要开发一个只用于我的机器上的Winforms应用程序(我使用C#btw),我可以产生多少个线程?

核心与我可以在任何时候运行的最大线程数有某种相关性吗?我是否需要找出有多少个线程在同一时间运行,如果是的话,这是可能的吗? (我知道有最小和最大线程的属性)?这是否依赖于线程池(该池中线程的最大数量是否更改?)。这是此帖子/线程的C#部分。

+0

你想要产生多少个线程?如果你完全担心任何限制,你可能会有太多限制。 – 2009-08-03 22:55:52

+0

我没有产生任何。这是假想的和未来的(我很好奇,好奇,我问的很多问题都与我目前的发展无关)。我想知道这个理论。 – dotnetdev 2009-08-03 22:57:36

回答

11

这一切都取决于,如果你的线程是活跃的(而不是等待IO)100%的时间,那么每个CPU有更多的1线程是没有意义的。但是,除非您正在执行复杂的数值计算,否则很少出现这种情况。

.Nets线程池有:http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx

线程池具有的每间可用 处理器 250工作线程,和1000 I/O完成 线程的默认大小。

所以,我会说,很少有建议任何人都可以给你,除了:

  • 评估与衡量指标。

在当你添加更多的线程一些点东西会变慢,由于上下文切换和同步。

0

虽然线程和内核之间存在松散的相关性(线程真正并行执行的唯一方法是让它们在不同的内核上运行,但知识的价值低于您的想象),真正的工作由操作系统调度程序完成,在这种情况下是Windows中的线程调度程序。

至于有多少线程可以创建,这将随系统而异。 ThreadPool类对产生自己的线程没有任何限制;它有一个线程池,它在内部管理自己。这些是您在检查ThreadPool类的属性时可以看到的值。然而,这并不是说你应该产生无限的线程;最终操作系统将花费更多的时间在你的线程之间切换,而不是实际上允许线程运行。通过基准测试找出有多少线程适合您的应用程序。

你究竟想要做什么?

0

我可以产生多少线程?

Waaay,waaay更多(数百或数千倍)比你想产卵为最佳的吞吐量。

(在Windows上)每个线程的限制我所知道的是:

  • 16位线程ID
  • 4-8KB分配用户空间堆栈(通常更多)
  • 非分页的内核空间的上下文和堆栈,像16KB

DOTNET大概增加了自己的东西,一堆每个线程的开销。 GC等。

一点式我喜欢使用一个WAG是:

threads = 2 * (cpu cores + active disk spindles) 

最佳数量通常是两个,一个因子之内。那个。理论上说,需要的线程是cpu核心的主动(出于显而易见的原因),但也有些线程会阻塞磁盘I/O。乘以2会使CPU有些事情要做,而其他线程被阻塞。

无论如何,从那开始并测量它。工作线程的数量是后来调整整个问题最简单的部分,所以现在不要担心太多。

0

只是想知道什么限制将首先通过启动许多线程命中。我写了下面这个简单的测试程序并试了一下。现在我假设记忆是限制因素。我能够运行1000个线程,但没有Thread.Sleep(),系统变得“没有反应”。 2000线程在1800线程左右启动后出现内存不足异常。 (笔记本具有英特尔Core 2 Duo T5800 2.0千兆赫,3.0吉布RAM和与.NET框架3.5 SP1上的Windows XP SP3运行 “几个” 应用程序)

UPDATE

的内存溢出异常是由一堆线程引起的。在线程构造函数中指定堆栈大小后(我使用了64 kB,但可能是目前我不知道的最小大小),我能够启动3500个线程(使用Thread.Sleep())。

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

namespace GeneralTestApplication 
{ 
    class Program 
    { 
     private static void Main() 
     { 
      Console.WriteLine("Enter the number of threads to start."); 

      while (!Int32.TryParse(Console.ReadLine(), out Program.numberThreads)) { } 

      Program.counters = new Int64[Program.numberThreads]; 

      Console.WriteLine("Starting {0} threads.", Program.numberThreads); 

      for (Int32 threadNumber = 0; threadNumber < Program.numberThreads; threadNumber++) 
      { 
       new Thread(Program.ThreadMethod).Start(threadNumber); 
      } 

      Console.WriteLine("Press enter to perform work on all threads."); 
      Console.ReadLine(); 

      Program.manualResetEvent.Set(); 

      Console.WriteLine("Press enter to stop all threads."); 
      Console.ReadLine(); 

      Program.stop = true; 

      Console.WriteLine("At least {0} threads ran.", Program.counters.Count(c => c > 0)); 

      Console.ReadLine(); 
     } 

     private static Int32 numberThreads = 0; 
     private static Int64[] counters = null; 
     private static readonly ManualResetEvent manualResetEvent = new ManualResetEvent(false); 
     private static volatile Boolean stop = false; 

     public static void ThreadMethod(Object argument) 
     { 
      Int32 threadNumber = (Int32)argument; 

      Program.manualResetEvent.WaitOne(); 

      while (!Program.stop) 
      { 
       Program.counters[threadNumber]++; 

       // Uncomment to simulate heavy work. 
       Thread.Sleep(10); 
      } 
     } 
    } 
} 
1

必须测量。也就是说,通过N核心,我通常在N + 12N线程之间产卵以获得最佳结果。但你必须测量。