After I joined Oracle, I thought about writing another step to control the CPU usage curve in "the beauty of programming", but there was always too much learning and there was no time. The program has been written for a long time and finally has a chance to post it. O (zookeeper) O ..
At the earliest time, I used C to achieve poor results, but I didn't perform debugging seriously at the time. At the beginning, C # was used to achieve good results, because C # has many convenient class libraries that can obtain CPU usage and control sleep time. In fact, it is easy to implement in C.
The overall algorithm IDEA is no longer repeated here. You can refer to the following link:
Http://blog.csdn.net/watkinsong/article/details/6865775
Http://blog.csdn.net/watkinsong/article/details/6867373
Http://blog.csdn.net/watkinsong/article/details/6867473
Http://blog.csdn.net/watkinsong/article/details/6867666
Http://blog.csdn.net/watkinsong/article/details/6870748
Http://blog.csdn.net/watkinsong/article/details/6871235
In this algorithm implementation, all the code is hosted on GitHub and the makefile compilation file is used.
Address: https://github.com/weixsong/aventador
The following is a simple example of code and results. The effect here is better than the sin curve implemented by C.
#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <sched.h>#include <unistd.h>extern const double PI = 3.1415926;// setup the cpu set of this program to run onint set_cpu(int id){ cpu_set_t mask; CPU_ZERO(&mask); CPU_SET(id, &mask); if (sched_setaffinity(0, sizeof(mask), &mask) == -1) { fprintf(stderr, "warning: could not set CPU affinity/n"); return 0; } return 1;}
#include <stdio.h>#include <stdlib.h>#include <time.h>#include <math.h>#include <unistd.h>#include "CPUtils.h"const int CPU_KERNEL_ID = 0x0003;const int SAMPLE_COUNT = 200;const int TIME_SLICE = 200; // ms in secondconst int TIME_TRANFORM = 1000; // change ms to uslong * busy_span;// init the busy span, this is used to control the cpu busy time for each sample pointint init_busySpan(int sample_count){busy_span = (long *)malloc(sample_count * sizeof(long));if(busy_span == NULL){return -1;}double radian = 0.0;double radianIncrement = 2.0 / (double)sample_count;int amplitude = (int)(TIME_SLICE / 2); // amplitude of sin curves, it means half of the time slice because sin() has negative valueint i;for(i = 0; i < sample_count; i++){busy_span[i] = (long)(amplitude + sin(radian * PI) * amplitude);radian = radian + radianIncrement;}return 1;}int main(void){if(set_cpu(CPU_KERNEL_ID) == 0){printf("cpu affinity set failed\n");}else{printf("cpu affinity set succeeded\n");}printf("clock per second:%ld \n", CLOCKS_PER_SEC);fflush(stdout);if(!(init_busySpan(SAMPLE_COUNT))){printf("init error \n");return 0;}int i = 0;long busy_time; // uslong sleep_time; // usclock_t begin;for(i = 0; ; i = (i + 1) % SAMPLE_COUNT){busy_time = busy_span[i] * TIME_TRANFORM;begin = clock();while((clock() - begin) < busy_time){// loop}sleep_time = (long)((TIME_SLICE - busy_span[i])) * TIME_TRANFORM;usleep(sleep_time);}return 1;}