zoukankan      html  css  js  c++  java
  • 让CPU占用率曲线听你指挥linux yongmou

      编程之美上的第一题,任务管理器上显示的使用率是这样计算的,在其刷新周期内实际执行的指令的条数/总共可以执行的条数。总的执行条数,可以通过主频算得,还要考虑超流水;实际执行条数就难算了。又注意到,CPU在执行运算时是全速进行的,所以可以让CPU在一小段时间内全速执行,一小段时间里什么也不干。

      另外,多核CPU会发生进程在CPU之间的切换,不过各种操作系统都有设置进程CPU亲和度的系统调用,linux系统是sched_setaffinity。

      下面这个程序可以运行在双核以上电脑上,你会看到一个CPU在画直线,另一个在画sin曲线。很好玩吧!

    #include <stdio.h>
    #include
    <math.h>

    #include
    <unistd.h>
    #include
    <sys/times.h>
    #define __USE_GNU
    #include
    <sched.h>


    // 设置进程在哪个cpu上运行
    void 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");
    }
    }

    clock_t Hz;
    // 时钟中断频率

    void draw_line(int cpu_id)
    {
    set_cpu(cpu_id);

    clock_t busy
    = Hz / 50; // 20ms
    clock_t idle = busy;
    clock_t start;
    while (1) {
    start
    = times(NULL);
    // busy loop
    while (times(NULL) - start <= busy)
    ;

    // idle loop
    usleep(idle * 1000 * 1000 / Hz);
    }
    }

    #define COUNT 200 // 分成200个小区间
    void draw_sin(int cpu_id)
    {
    set_cpu(cpu_id);

    int i;
    const double PI = 3.1415926;
    const clock_t INTERVAL = Hz * 2;
    clock_t busy_span[COUNT];
    clock_t idle_span[COUNT];

    clock_t half
    = INTERVAL / 2;
    double radian = 0.0;
    for (i=0; i < COUNT; ++i) { // 预计算
    busy_span[i] = half * (1 + sin(PI * radian));
    idle_span[i]
    = INTERVAL - busy_span[i];
    radian
    += (2 / COUNT);
    }

    clock_t start;
    for (i = 0; 1; ++i) {
    i
    %= COUNT;
    start
    = times(NULL);
    while (times(NULL) - start <= busy_span[i])
    ;
    usleep(idle_span[i]
    * 1000 * 1000 / Hz);
    }
    }

    int main()
    {
    Hz
    = sysconf(_SC_CLK_TCK);

    pid_t pid;
    pid
    = fork();
    if (pid == 0) {
    draw_line(
    0);
    }
    else {
    draw_sin(
    1);
    }
    return 0;
    }

    执行的效果:

  • 相关阅读:
    接口的幂等性原则
    SpringBoot热部署-解决方案
    @Resource 与 @Service注解的区别
    软件概要设计做什么,怎么做
    First Show
    Glide源码解析一,初始化
    android使用giflib加载gif
    android的APT技术
    RxJava的concat操作符
    RxJava基本使用
  • 原文地址:https://www.cnblogs.com/liyongmou/p/2085816.html
Copyright © 2011-2022 走看看