您的位置:首页 > 运维架构 > Linux

<编程之美>1.1: 让CPU占用率曲线听你指挥(under Linux)

2012-11-12 22:17 471 查看
拿到这本书, 第一题就挺有意思: 让CPU曲线走一个正弦曲线.

注意到 1. 一个死循环会使得CPU占满 2. 不开其他东西时, CPU跑的是shell+后台一些东向, 占用是比较低的(10%-20%)

那么, 程序需要的就是在这两种状态之间找到平衡. 我们可以让程序主体跑死循环, 在之前设定一个定时器(setitimer()), 定时把程序sleep掉, 就会达到需要的占用率.

之后看书上的解法, 他没用定时器, 用的一个叫GetTickCount()的win下api. 道理是一样的.

另外, 他是在之前就把正弦曲线的各个采样点数据存在一个数组里, 我之前是需要每次sleep时去计算. 这个他的更好.

编译的时候用gcc -lm -o cpuline cpuline.c.

运行的时候注意taskset 0x00000001 ./cpuline. 我的机器是双核的, 不然内核跑一会就会把程序放另一个CPU上.

用这个能限制在第一个CPU上. man了一下, taskset还是<Linux Kernel Development>的作者写的, 哈哈.

以下是代码(c)和运行效果:

/* This is cpuline.old.c written by leaforestd@gmail.com.
* (use gcc -lm -o cpuline.old cpuline.old.c
* and  taskset 0x00000001 ./cpuline.old)
*/
#include <math.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#define SAMPLE_COUNT 200
#define REFRESH_USEC 50000 /* one cycle: SAMPLE_COUNT * REFRESH_USEC / 10^6 (10s, refresh: 0.05s)*/

const double Pi = 3.1415926535;
int Sleep_array[SAMPLE_COUNT];

void sleep_counter();
void initial_array(void);

int main() {
int retval = 0; /* error if -1 */
struct itimerval timer;

initial_array();

/* timer */
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = REFRESH_USEC;
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = REFRESH_USEC;
if ((retval = setitimer(ITIMER_REAL, &timer, 0)) == -1) {
printf("setitimer error\n");
return retval;
}

/* signal */
if ((retval = (int)signal(SIGALRM, sleep_counter)) == -1) {
printf("signal error\n");
return retval;
}

/* infinite loop */
while (1)
;
return 0;
}

void sleep_counter() {
static int index = 0;
usleep(Sleep_array[index]);

if (index == 199)
index = 0;
else
index++;
}

void initial_array(void) {
int index;
double percent;
double i = 0;

for (index = 0; index < SAMPLE_COUNT; index++) {
percent = (sin(i / 100 * Pi) + 1) / 2; /* range: [0, 1] */
Sleep_array[index] = (int)(percent * REFRESH_USEC + 0.5);
i++;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐