技术开发 频道

多处理器的线程依赖


【IT168技术文档】

  首先要搞清楚的是,托管代码中的线程(Thread)并不是真的线程(OS Thread)。它只是逻辑上我们划定的线程。逻辑上的线程并不执行,实际执行的是物理线程或者叫OS线程。而通常来说,每一个逻辑线程都对应的关联于某一条物理线程,这种关系一直维系到该逻辑线程的生命周期结束。要设置线程的处理器依赖我们先要得到当前实际运行的物理OS Thread或者叫物理线程,这时候需要使用Windows API – GetCurrentThreadId 。
class KernalHelper { [DllImport("kernel32")] public static extern int GetCurrentThreadId(); }
  然后再通过当前的osThreadID找到对应的ProcessThread,并设定其ProcessorAffinity。

  以下代码演示了如何在一台双核PC的资源管理器里划出正弦曲线:
private fields#region private fields private static int rounds = 0; private static int MAXROUND = 60; private static long[] sins = new long[MAXROUND]; private static PerformanceCounter pc; private static bool tag = false; #endregion static void Main(string[] args) { Thread WatchThread = new Thread(() => GenerateSin(1)); WatchThread.Start(); Console.WriteLine("Press any key to break"); Console.ReadKey(); WatchThread.Abort(); } public static void GenerateSin(int num) { //对当前物理线程设置处理器依赖 int osThreadId = KernalHelper.GetCurrentThreadId(); foreach (ProcessThread pt in Process.GetCurrentProcess().Threads) { if (osThreadId == pt.Id) { pt.ProcessorAffinity = (IntPtr)num; } } try { tag = true; //获得处理器的使用率 pc = new PerformanceCounter("Processor", "% Processor Time", "_Total"); for (int a = 0; a < MAXROUND; a++) { //六十个点的,振幅为5000000周期为60的正弦序列 sins[a] = (long)(5000000 * Math.Sin(Math.PI * a / (double)MAXROUND * 2f)) + 5000000; } long t1, t2; long TimeSlide; while (tag) { t1 = pc.RawValue + sins[rounds % MAXROUND]; TimeSlide = Stopwatch.GetTimestamp() + Stopwatch.Frequency; t2 = TimeSlide - Stopwatch.Frequency + sins[rounds % MAXROUND] * Stopwatch.Frequency / 10000000; while (pc.RawValue < t1) { Thread.Sleep(10); } while (Stopwatch.GetTimestamp() < TimeSlide) ; rounds++; } } catch (Exception ex) { Console.Write(ex.Message); } finally { pc.Close(); } }
0
相关文章