目標: 實現在指定核心顯示正選曲線。
基礎原理: Windows任務管理器(Task Manager)所顯示的CPU占用率指的是一段時間內cpu使用時間所占的百分比,而不是CPU有多少被用掉了。 舉個例子說一下:比如一個員工一天的工作時間是8小時,他用了4小時把任務完成,於是他這一天的使用率就是50%。對於CPU而言,在一秒鍾里,CPU被使用了多少毫秒,也就是CPU在這一秒鍾里的使用率。
基於這個基本原理,就有了一個理論上的實踐方式: 1.確定一個工作時間片 2.指定這個時間工作時間片里CPU的工作和空閑時間。 3.指定的方法應根據需求
技術准備: 首先:實現的目標是利用任務管理器中某個核心顯示正選曲線,所以應注意一下兩點: 1.任務管理器無法顯示負值。 2.利用正選曲線函數來填充工作時間片。 其次:Cpu核心的指定:由此參看:多核處理器中,指定線程運行在指定CPU核心上
C#實現
View Code
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Runtime.InteropServices;
6 using System.Threading;
7 using System.Diagnostics;
8
9 namespace ConsoleApplication1
10 {
11 public 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
54 //讓指定的cpu占用率成直線,保持在50%左右
55 //int busyTime = 10;
56 //int idleTime = busyTime;
57 //Int64 startTime = 0;
58 //while(true)
59 //{
60 // startTime = System.Environment.TickCount;
61 // while ((System.Environment.TickCount - startTime) <= busyTime)
62 // ;
63 // System.Threading.Thread.Sleep(idleTime);
64 //}
65
66 //可以手工輸入1-100任意數值的暫用率,動態設定
67 //Console.Write("Which percent you will to use (Range(1-100),Start from 1):");
68 //string percent = Console.ReadLine();
69 //float n = 1;
70 //if (float.TryParse(percent, out n))
71 //{
72 // MakeUsage(n);
73 //}
74 //else
75 //{
76 // MakeUsage(1);
77 //}
78
79 //正弦曲線
80 //split*count=2;也就是正弦函數的周期2 Pi,也就是把一個周期的細分為200份
81 //double split = 0.01;
82 //int count = 200;
83
84 //double pi = 3.1415962525;
85
86 ////工作周期 300 ms
87 //int interval = 300;
88
89 ////每個工作周期里工作和空閑的毫秒數
90 //int[] busySpan = new int[count];
91 //int[] idealSpan = new int[count];
92
93 ////根據正弦函數計算並填入每個工作周期的工作和空閑毫秒數
94 //int half = interval / 2;
95 //double radian = 0.0;
96 //for (int i = 0; i < count; i++)
97 //{
98 // busySpan[i] = (int)(half + Math.Sin(pi * radian) * half);
99 // idealSpan[i] = interval - busySpan[i];
100 // radian += split;
101 //}
102
103 //uint startTime = 0;
104 //int j = 0;
105 //while (true)
106 //{
107 // j = j % count;
108 // startTime = GetTickCount();
109 // while ((GetTickCount() - startTime) <= busySpan[j])
110 // {
111 // ;
112 // }
113 // Thread.Sleep(idealSpan[j]);
114 // j++;
115 //}
116
117 }
118
119 static void MakeUsage(float level)
120 {
121 PerformanceCounter p=new PerformanceCounter("Processor Information","% Processor Time","_Total");
122 if(p==null)
123 return;
124 while(true)
125 {
126 if(p.NextValue()>=level)
127 System.Threading.Thread.Sleep(10);
128 }
129 }
130 //函數中的參數 dwThreadAffinityMask 為無符號長整型,用位標識那個核心
131 //比如:為簡潔使用四位表示
132 //0x0001表示核心1,
133 //0x0010表示核心2,
134 //0x0100表示核心3,
135 //0x1000表示核心4
136 static ulong SetCpuID(int id)
137 {
138 ulong cpuid = 0;
139 if (id < 0 || id >= System.Environment.ProcessorCount)
140 {
141 id = 0;
142 }
143 cpuid |= 1UL << id;
144 return cpuid;
145 }
146 }
147 }
