我们可以设置两个线程或两个任务在C#应用程序中以不同的处理器关系执行吗?如何在.NET中设置处理器相关性?
我已阅读约SetThreadAffinityMask
,但没有找到如何应用的例子。
或者,TPL(任务并行库)是否有任何方式执行两个线程/高优先级任务以使用100%的CPU?
我们可以设置两个线程或两个任务在C#应用程序中以不同的处理器关系执行吗?如何在.NET中设置处理器相关性?
我已阅读约SetThreadAffinityMask
,但没有找到如何应用的例子。
或者,TPL(任务并行库)是否有任何方式执行两个线程/高优先级任务以使用100%的CPU?
其实OS能够负载平衡你的内核/处理器,但是如果你想这样做明确使用PInvoke提到。你传递线程的id(不是管理的)!和掩码 - 内核的比特数组。
Process
和ProcessThread
对象具有可直接操作读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展示了如何设置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;
}
}
}
复制粘贴从https://msdn.microsoft.com/en-us/library/system.diagnostics.processthread.processoraffinity.aspx。应该引用来源... – Marc 2015-10-26 10:04:42
实际上,.NET Framework和Windows很好地管理线程,将它们平均分配到每个处理器上。但是,可以使用Process
和ProcessThread
手动处理线程的分配。
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
问:“我们可以设置两个线程还是两个任务,以便在C#应用程序中以不同的处理器关系执行?”请注意,OP在同一个_process_中要求不同的_threads_。所以这个问题不是关于_process_,而是_thread_关系。 – 2011-01-07 11:06:13
有'Thread.SetProcessorAffinity()',但它只适用于XNA的Xbox 360.据我所知,在vanilla .NET中没有OOTB解决方案。 – 2011-01-07 11:11:02
@andras:好点,我想我错过了一点。还有一种方法可以为线程执行此操作,并且我相应地编辑了示例。谢谢! – Phillip 2011-01-12 00:41:45