一、索引
0.目标
1.基础原理
2.技术准备
3.C#实现
4.下载完整示例
二、实现过程
目标:
实现在指定核心显示正选曲线。
基础原理:
Windows任务管理器(Task Manager)所显示的CPU占用率指的是一段时间内cpu使用时间所占的百分比,而不是CPU有多少被用掉了。
举个例子说一下:比如一个员工一天的工作时间是8小时,他用了4小时把任务完成,于是他这一天的使用率就是50%。对于CPU而言,在一秒钟里,CPU被使用了多少毫秒,也就是CPU在这一秒钟里的使用率。
基于这个基本原理,就有了一个理论上的实践方式:
1.确定一个工作时间片
2.指定这个时间工作时间片里CPU的工作和空闲时间。
3.指定的方法应根据需求
技术准备:
首先:实现的目标是利用任务管理器中某个核心显示正选曲线,所以应注意一下两点:
1.任务管理器无法显示负值。
2.利用正选曲线函数来填充工作时间片。
其次:Cpu核心的指定:由此参看:多核处理器中,指定线程运行在指定CPU核心上
代码
1 //http://www.liveoo.net/2010/08/bitc-cp1.html
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.Runtime.InteropServices;
7 using System.Threading;
8
9 namespace Cpt1
10 {
11 class Program
12 {
13 [DllImport("kernel32.dll")]
14 static extern uint GetTickCount();
15
16 //SetThreadAffinityMask 指定hThread 运行在 核心 dwThreadAffinityMask
17 [DllImport("kernel32.dll")]
18 static extern UIntPtr SetThreadAffinityMask(IntPtr hThread,
19 UIntPtr dwThreadAffinityMask);
20
21 //得到当前线程的handler
22 [DllImport("kernel32.dll")]
23 static extern IntPtr GetCurrentThread();
24
25 static void Main(string[] args)
26 {
27 Thread t1 = new Thread(new ParameterizedThreadStart(sinaG));
28 Console.Write("Which core you will to use (Start from 0):");
29 string core = Console.ReadLine();
30 int coreNumber = 0;
31 try
32 {
33 coreNumber = Int32.Parse(core);
34 }
35 catch
36 {
37 coreNumber = 0;
38 }
39 t1.Start(coreNumber);
40 }
41 static void sinaG(object coreNumber)
42 {
43 int core = 0;
44 try
45 {
46 core = (int)coreNumber;
47 }
48 catch
49 {
50 core = 0;
51 }
52 SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(SetCpuID(core)));
53 //指定在核心1上运行
54 //SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(SetCpuID(0)));
55 //指定在核心2上运行
56 //SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(SetCpuID(1)));
57 //指定在核心3上运行
58 //SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(SetCpuID(2)));
59 //指定在核心4上运行
60 //SetThreadAffinityMask(GetCurrentThread(), new UIntPtr(SetCpuID(3)))
61
62 //split*count=2;也就是正弦函数的周期2 Pi,也就是把一个周期的细分为200份
63 double split = 0.01;
64 int count = 200;
65
66 double pi = 3.1415962525;
67
68 //工作周期 300 ms
69 int interval = 300;
70
71 //每个工作周期里工作和空闲的毫秒数
72 int[] busySpan = new int[count];
73 int[] idealSpan = new int[count];
74
75 //根据正弦函数计算并填入每个工作周期的工作和空闲毫秒数
76 int half = interval / 2;
77 double radian = 0.0;
78 for (int i = 0; i < count; i++)
79 {
80 busySpan[i] = (int)(half + Math.Sin(pi * radian) * half);
81 idealSpan[i] = interval - busySpan[i];
82 radian += split;
83 }
84
85 uint startTime = 0;
86 int j = 0;
87 while (true)
88 {
89 j = j % count;
90 startTime = GetTickCount();
91 while ((GetTickCount()-startTime)<=busySpan[j])
92 {
93 ;
94 }
95 Thread.Sleep(idealSpan[j]);
96 j++;
97 }
98 }
99 //函数中的参数 dwThreadAffinityMask 为无符号长整型,用位标识那个核心
100 //比如:为简洁使用四位表示
101 //0x0001表示核心1,
102 //0x0010表示核心2,
103 //0x0100表示核心3,
104 //0x1000表示核心4
105 static ulong SetCpuID(int id)
106 {
107 ulong cpuid = 0;
108 if (id < 0 || id >= System.Environment.ProcessorCount)
109 {
110 id = 0;
111 }
112 cpuid |= 1UL << id;
113 return cpuid;
114 }
115 }
116 }
117