编写代码以使CPU使用率显示为正弦波

以您最喜欢的语言编写代码,让Windows任务pipe理器代表CPU使用历史logging中的正弦波。

这是来自微软中国的技术面试问答。 我认为这是一个很好的问题。 尤其值得了解的是候选人如何理解和解决问题。

编辑 :如果可能涉及多核(cpu)的情况,这是一个好点。

Windows中的线程时间片是40ms,iirc,因此可能是一个很好的数字,可以用作100%的标记。

unsigned const TIME_SLICE = 40; float const PI = 3.14159265358979323846f; while(true) { for(unsigned x=0; x!=360; ++x) { float t = sin(static_cast<float>(x)/180*PI)*0.5f + 0.5f; DWORD busy_time = static_cast<DWORD>(t*TIME_SLICE); DWORD wait_start = GetTickCount(); while(GetTickCount() - wait_start < busy_time) { } Sleep(TIME_SLICE - busy_time); } } 

这会给大约14秒的时间。 显然,这里假定系统中没有其他重要的CPU使用情况,并且只能在单个CPU上运行。 这些在现实中都不是那么普遍。

这里有一个稍微修改的@ flodin在Python中的解决方案 :

 #!/usr/bin/env python import itertools, math, time, sys time_period = float(sys.argv[1]) if len(sys.argv) > 1 else 30 # seconds time_slice = float(sys.argv[2]) if len(sys.argv) > 2 else 0.04 # seconds N = int(time_period / time_slice) for i in itertools.cycle(range(N)): busy_time = time_slice / 2 * (math.sin(2*math.pi*i/N) + 1) t = time.clock() + busy_time while t > time.clock(): pass time.sleep(time_slice - busy_time); 

CPU曲线可以使用time_periodtime_slice参数进行微调。

好吧,我有一个不同的,可能比我的第一个答案更好的解决方案。

而不是试图操纵CPU,而是钩入任务管理器应用程序,强制它绘制你想要它,而不是CPU的结果。 接管绘制图形的GDI对象,等等。“作弊”的排序,但他们并没有说你必须操纵CPU

或者甚至挂接来自得到CPU%的任务管理器的调用,反而返回一个正弦结果。

如今,PC运行的字节数百(数千)个线程,我认为唯一可以接近的方法就是尽可能快地轮询CPU使用率,如果使用率低于应该在曲线上的位置,发射一个简单的方法,只是搅动数字。 这至少会在需要的时候带来典型的低使用率UP,但是我不能想到一个好的方法来降低它,而不会以某种方式来控制其他线程,并且执行诸如强制优先级更低的操作。

像这样的东西:

 while(true) { for(int i=0;i<360;i++) { // some code to convert i into radians if needed ... Thread.Sleep(Math.Sin(i)*something_that_makes_it_noticeable_number_of_ms+something_that_makes_it_non_negative) // some work to make cpu busy, may be increased to bigger number to see the influence on the cpu. for(j=0;j<100;j++); } }