写一个程序,让用户决定Windows任务管理器(Task Manager)的CPU占用率。例如,可以实现下面三种情况:
观察我们的任务管理器,可以发现:
大约是1秒钟更新一次,一般情况下,使用率都很低,当用户运行一个程序,执行复杂操作时,cpu的使用率会急剧升高。
通过查阅资料可以知道:
在任务管理器的一个刷新周期内,CPU忙(执行应用程序)的时间和刷新周期总时间的比率,就是CPU的占用率。
想要操作CPU的使用率曲线,就需要使CPU在一段时间内跑busy和idle两个不同的循环。
对于一个空循环for(i = 0; i < n; i++)如何估算最合适的n值?
需要查阅资料:
假设这段代码要运行的CPU是P4 2.4Ghz(2.4 * 10 的9次方个时钟周期每秒)现代CPU每个时钟周期可以执行两条以上的代码,我们取平均值两条,CPU一秒钟可以运行空循环 2.4 * 10的9次方*2次。
我们可以使n低于这个数字,比如n = 9600000,sleep(10).
代码:
int main() {for(;;) {for(int i = 0; i < 9600000; i++) {;sleep(10);}return 0;
}
想要让cpu的使用率成为一条正弦曲线,可以把一条正弦曲线0~2π之间的弧度等分成200份进行抽样,计算每个抽样点的振幅,然后每隔一段时间(例如300ms)取下一个抽样点,并让cpu工作对应振幅的时间。
package arithmetic;import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;class drawSin implements Runnable {public void run() {final double SPLIT = 0.01;final int COUNT = (int)(2 / SPLIT);final double PI = Math.PI;final int interval = 100;long[] busy = new long[COUNT];long[] idle = new long[COUNT];int half = interval / 2;double x = 0.0;for(int i = 0; i < COUNT; i++) {busy[i] = (long)(half + (Math.sin(PI * x) * half))/ 2;idle[i] = interval - busy[i];x += SPLIT;}long start = 0;int j = 0;while (true) {j = j % COUNT;start = System.currentTimeMillis();while(System.currentTimeMillis() - start < busy[j]) ;try {Thread.sleep(idle[j]);} catch(InterruptedException e) {e.printStackTrace();}j++;}}
}
public class Main {public static void main(String[] args) throws Exception {Runtime runtime = Runtime.getRuntime();ExecutorService executorService = Executors.newFixedThreadPool(runtime.availableProcessors());for (int i = 0; i < runtime.availableProcessors(); i++){//每个核心都上一个线程executorService.execute(new drawSin());}executorService.shutdown();}
}