2010-03-24 52 views
19

我们可以设置两个线程或两个任务在C#应用程序中以不同的处理器关系执行吗?如何在.NET中设置处理器相关性?

我已阅读约SetThreadAffinityMask,但没有找到如何应用的例子。

或者,TPL(任务并行库)是否有任何方式执行两个线程/高优先级任务以使用100%的CPU?

回答

2

其实OS能够负载平衡你的内核/处理器,但是如果你想这样做明确使用PInvoke提到。你传递线程的id(不是管理的)!和掩码 - 内核的比特数组。

39

ProcessProcessThread对象具有可直接操作读IntPtr类型/更改亲和力的多达64个处理器的ProcessorAffinity属性:

 

using System.Diagnostics; 
... 
    Process Proc = Process.GetCurrentProcess(); 
    long AffinityMask = (long)Proc.ProcessorAffinity; 
    AffinityMask &= 0x000F; // use only any of the first 4 available processors 
    Proc.ProcessorAffinity = (IntPtr)AffinityMask; 

    ProcessThread Thread = Proc.Threads[0]; 
    AffinityMask = 0x0002; // use only the second processor, despite availability 
    Thread.ProcessorAffinity = (IntPtr)AffinityMask; 
... 
 

您还可以使用线程的IdealProcessor属性,以允许调度更喜欢在指定的处理器上运行线程(不保证)。

是的,就是这么简单:)

参考:MSDN ProcessThread.ProcessorAffinity Property

+2

问:“我们可以设置两个线程还是两个任务,以便在C#应用程序中以不同的处理器关系执行?”请注意,OP在同一个_process_中要求不同的_threads_。所以这个问题不是关于_process_,而是_thread_关系。 – 2011-01-07 11:06:13

+0

有'Thread.SetProcessorAffinity()',但它只适用于XNA的Xbox 360.据我所知,在vanilla .NET中没有OOTB解决方案。 – 2011-01-07 11:11:02

+0

@andras:好点,我想我错过了一点。还有一种方法可以为线程执行此操作,并且我相应地编辑了示例。谢谢! – Phillip 2011-01-12 00:41:45

1

下面的示例MSDN展示了如何设置ProcessorAffinity属性的Notepad到第一处理器的实例。

using System; 
using System.Diagnostics; 

namespace ProcessThreadIdealProcessor 
{ 
    class Program 
    { 
    static void Main(string[] args) 
     { 
     // Make sure there is an instance of notepad running. 
     Process[] notepads = Process.GetProcessesByName("notepad"); 
     if (notepads.Length == 0) 
      Process.Start("notepad"); 
      ProcessThreadCollection threads; 
      //Process[] notepads; 
      // Retrieve the Notepad processes. 
      notepads = Process.GetProcessesByName("Notepad"); 
      // Get the ProcessThread collection for the first instance 
      threads = notepads[0].Threads; 
      // Set the properties on the first ProcessThread in the collection 
      threads[0].IdealProcessor = 0; 
      threads[0].ProcessorAffinity = (IntPtr)1; 
     } 
    } 
} 
+2

复制粘贴从https://msdn.microsoft.com/en-us/library/system.diagnostics.processthread.processoraffinity.aspx。应该引用来源... – Marc 2015-10-26 10:04:42

0

实际上,.NET Framework和Windows很好地管理线程,将它们平均分配到每个处理器上。但是,可以使用ProcessProcessThread手动处理线程的分配

using System; 
using System.Diagnostics; 
using System.Threading; 

namespace ThreadTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      //Get the our application's process. 
      Process process = Process.GetCurrentProcess(); 

      //Get the processor count of our machine. 
      int cpuCount = Environment.ProcessorCount; 
      Console.WriteLine("CPU Count : {0}", cpuCount); 

      //Since the application starts with a few threads, we have to 
      //record the offset. 
      int offset = process.Threads.Count; 
      Thread[] threads = new Thread[cpuCount]; 
      Console.WriteLine(process.Threads.Count); 
      LogThreadIds(process); 

      //Create and start a number of threads that equals to 
      //our processor count. 
      for (int i = 0; i < cpuCount; ++i) 
      { 
       Thread t = new Thread(new ThreadStart(Calculation)) 
       { IsBackground = true }; 
       t.Start(); 
      } 

      //Refresh the process information in order to get the newest 
      //thread list. 
      process.Refresh(); 
      Console.WriteLine(process.Threads.Count); 
      LogThreadIds(process); 

      //Set the affinity of newly created threads. 
      for (int i = 0; i < cpuCount; ++i) 
      { 
       //process.Threads[i + offset].ProcessorAffinity = (IntPtr)(1L << i); 
       //The code above distributes threads evenly on all processors. 
       //But now we are making a test, so let's bind all the threads to the 
       //second processor. 
       process.Threads[i + offset].ProcessorAffinity = (IntPtr)(1L << 1); 
      } 
      Console.ReadLine(); 
     } 
     static void Calculation() 
     { 
      //some extreme loads. 
      while (true) 
      { 
       Random rand = new Random(); 
       double a = rand.NextDouble(); 
       a = Math.Sin(Math.Sin(a)); 
      } 
     } 
     static void LogThreadIds(Process proc) 
     { 
      //This will log out all the thread id binded to the process. 
      //It is used to test whether newly added threads are the latest elements 
      //in the collection. 
      Console.WriteLine("===Thread Ids==="); 
      for (int i = 0; i < proc.Threads.Count; ++i) 
      { 
       Console.WriteLine(proc.Threads[i].Id); 
      } 
      Console.WriteLine("===End of Thread Ids==="); 
     } 
    } 
} 

现在检查任务管理器,我们可以看到第二个处理器正在处理所有的工作负载。 The task manager window

相关问题