开发者社区> 问答> 正文

linux下调控CPU的占用率

linux下,如何让cpu达到指定占用率。例如:给定占用率为50%,CPU达到50%的占用率,并且要保持住

展开
收起
小旋风柴进 2016-06-03 09:58:21 3162 0
1 条回答
写回答
取消 提交回答
  • 使cpu占用率50%

    首先定义一下cpu的利用率:CPU执行非系统空闲进程的时间 / CPU总的执行时间 = run / (run+sleep)

    具体内容参考这个链接 http://server.51cto.com/sCollege-188250.htm

    下面是这段代码:

    #include
    #include
    
    int main(int argc, char* argv[])
    {
    struct timeval tv;
    long long start_time,end_time;
    while(1)
    {
    gettimeofday(&tv,NULL);
    start_time = tv.tv_sec*1000000 + tv.tv_usec;
    end_time = start_time;
    while((end_time - start_time) < 60000)
    {
    gettimeofday(&tv,NULL);
    end_time = tv.tv_sec*1000000 + tv.tv_usec;
    }
    usleep(60000);
    }
    // }
    return 0;
    }
    
    这段程序只能使当前进程的cpu使用率为50%,并不能画出一条50%的直线
    
    首先是SMP的原因,所以想要画出一条50%的直线,第一个要做的是绑定该进程到特定的cpu
    
    修改之后得到如下代码
    
    #include
    #include
    #include
    #include
    #include
    
    #define __USE_GNU
    #include
    #include
    #include
    
    int main(int argc, char* argv[])
    {
    int num = sysconf(_SC_NPROCESSORS_CONF);
    int created_thread = 0;
    int myid;
    int i;
    int j = 0;
    
        cpu_set_t mask;
        cpu_set_t get;
    
        if (argc != 2)
        {
                printf("usage : ./cpu num\n");
                exit(1);
        }
    
        myid = atoi(argv[1]);/*绑定到的cpu*/
    
        printf("system has %i processor(s). \n", num);
    
        CPU_ZERO(&mask);
        CPU_SET(myid, &mask); /*掩码*/
    
        if (sched_setaffinity(0, sizeof(mask), &mask) == -1)/*0指当前进程*/
        {
                printf("warning: could not set CPU affinity, continuing...\n");
        }
    
        CPU_ZERO(&get);
        if (sched_getaffinity(0, sizeof(get), &get) == -1)
        {
                printf("warning: cound not get cpu affinity, continuing...\n");
        }
        for (i = 0; i < num; i++)
        {
            if (CPU_ISSET(i, &get))
            {
                printf("this process %d is running processor : %d\n",getpid(), i);
            }
        }
        struct timeval tv;
        long long start_time,end_time;
        while(1)
        {
            gettimeofday(&tv,NULL);
            start_time = tv.tv_sec*1000000 + tv.tv_usec;
            end_time = start_time;
            while((end_time - start_time) < 60000)
            {
                gettimeofday(&tv,NULL);
                end_time = tv.tv_sec*1000000 + tv.tv_usec;
            }
            usleep(60000);
        }
    
        return 0;
    }
    
    另外还需要注意的是,cpu本身还运行了一些程序,他们也占着资源,所以该进程并不能很好的使某个cpu使用率维持在50%,
    
    想要改进有两个思路
    
    1)把cpu1上面的进程都转走,做的更绝的话把中断请求也转走
    
    把进程都转走,这个可以借鉴上面的sched_setaffinity函数,比如我的机器只有两个cpu,我就把所有的进程都转到cpu0上面
    
    修改/proc/irq/中断号/smp_affinity文件的内容,把中断也转走
    内容00000001表示该中断请求在cpu0上运行,
    内容00000003表示该中断请求在cpu0和cpu1上运行,
    
    2)第二个思路是 动态监控cpu的利用率 v,然后用50%-v得到 画线程序所需要占用的cpu利用率,但是如果cpu1的利用率已经超过50%,那就没办法了。其中最关键就是获取当前cpu的利用率,然后再修改之前的程序,调节idle 和run的比率
    
    具体操作是: cpu的状态放在/proc/stat中
    
    yandong@yandong-pc:~$ cat /proc/stat 
    cpu 317625 3414 201038 1352933 13696 21 2117 0 0 0
    cpu0 158901 1841 99148 677057 6693 8 1417 0 0 0
    cpu1 158724 1572 101889 675876 7002 13 699 0 0 0
    intr 9118805 1513856 6222 0 0 128 0 0 0 1 994 0 0 162 0 0 0 ...
    ctxt 17067117
    btime 1372081120
    processes 8140
    procs_running 1
    procs_blocked 0
    softirq 3053746 0 1450608 20 4054 61209 0 767379 274483 4158 491835
    
    其中个数据的意思是
    
    参数 解释
    user (432661)
    
    nice (13295)
    
    system (86656) 
    idle (422145968)
    
    iowait (171474)
    
    irq (233) 
    softirq (5346) 
    从系统启动开始累计到当前时刻,用户态的CPU时间(单位:jiffies) ,不包含 nice值为负进程。1jiffies=0.01秒
    从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间(单位:jiffies)
    从系统启动开始累计到当前时刻,核心时间(单位:jiffies)
    从系统启动开始累计到当前时刻,除硬盘IO等待时间以外其它等待时间(单位:jiffies)
    从系统启动开始累计到当前时刻,硬盘IO等待时间(单位:jiffies) ,
    从系统启动开始累计到当前时刻,硬中断时间(单位:jiffies)
    从系统启动开始累计到当前时刻,软中断时间(单位:jiffies)
    
    “intr”这行给出中断的信息,第一个为自系统启动以来,发生的所有的中断的次数;然后每个数对应一个特定的中断自系统启动以来所发生的次数。
    
    “ctxt”给出了自系统启动以来CPU发生的上下文交换的次数。
    
    “btime”给出了从系统启动到现在为止的时间,单位为秒。
    
    “processes (total_forks) 自系统启动以来所创建的任务的个数目。
    
    “procs_running”:当前运行队列的任务的数目。
    
    “procs_blocked”:当前被阻塞的任务的数目。
    
    那么CPU利用率可以使用以下两个方法。先取两个采样点,然后计算其差值:
    
    cpu usage=(idle2-idle1)/(cpu2-cpu1)*100 
    cpu usage=[(user_2 +sys_2+nice_2) - (user_1 + sys_1+nice_1)]/(total_2 - total_1)*100
    
    这种计算用shell比较快捷:
    
    #!/bin/sh
    
    ##echo user nice system idle iowait irq softirq
    
    CPULOG_1=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
    
    SYS_IDLE_1=$(echo $CPULOG_1 | awk '{print $4}')
    
    Total_1=$(echo $CPULOG_1 | awk '{print $1+$2+$3+$4+$5+$6+$7}')
    
    sleep 5
    
    CPULOG_2=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
    
    SYS_IDLE_2=$(echo $CPULOG_2 | awk '{print $4}')
    
    Total_2=$(echo $CPULOG_2 | awk '{print $1+$2+$3+$4+$5+$6+$7}')
    
    SYS_IDLE=expr $SYS_IDLE_2 - $SYS_IDLE_1
    
    Total=expr $Total_2 - $Total_1
    
    SYS_USAGE=expr $SYS_IDLE/$Total*100 |bc -l
    
    SYS_Rate=expr 100-$SYS_USAGE |bc -l
    
    Disp_SYS_Rate=expr "scale=3; $SYS_Rate/1" |bc
    
    echo $Disp_SYS_Rate%
    
    
    
    for i in seq 1 $(cat /proc/cpuinfo |grep "physical id" |wc -l); do dd if=/dev/zero of=/dev/null & done

    说明:

    cat /proc/cpuinfo |grep "physical id" | wc -l 可以获得CPU的个数, 我们将其表示为N.

    seq 1 N 用来生成1到N之间的数字

    for i in seq 1 N; 就是循环执行命令,从1到N

    dd if=/dev/zero of=/dev/null 执行dd命令, 输出到/dev/null, 实际上只占用CPU, 没有IO操作.

    由于连续执行N个(N是CPU个数)的dd 命令, 且使用率为100%, 这时调度器会调度每个dd命令在不同的CPU上处理.

    最终就实现所有CPU占用率100%

    2019-07-17 19:26:01
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Alibaba Cloud Linux 3 发布 立即下载
ECS系统指南之Linux系统诊断 立即下载
ECS运维指南 之 Linux系统诊断 立即下载