让你的程序独占一个处理器


  最近需要用ejtag调试CRIU程序中遇到的BUSERROR的问题,环境准备的第一件事就是要让被调试的程序独占一个处理器(核)。 怎么做呢? 方法如下:
一、准备工作:隔离出cpu某核(此核不再参与进程调度)

此步操作需要root权限才可以完成。
具体修改在/ boot/boot.cf的kernel列最末尾加上isolcpus=x,y,… (代表将CPUx CPUy隔离)

title 'Loongnix 1.0 (Loongson)'
	...
	args  root=/dev/sda3 console=tty console=ttyS0,115200 rw isolcpus=0

  这里,我设置了把cpu0隔离出去,然后重启电脑后配置即可生效。
这里isolcpus是传给内核的参数,意为通知内核进程调度模块处理器0不参与进程调度(就算是其他处理器已经负载100%)。如果你要隔离多个处理器可以使用逗号分割,例如我要隔离0号和3号处理器,那么可以写成 isolcpus=0,3

  还需要说明一点的是,我用的主机固件是PMON。如果主机固件是UEFI,需要修改的配置是/boot/EFI/BOOT/grub.cfg

那么如何验证此修改起效了呢?

验证隔离的方式
1、 编写用cpu烤鸡蛋的程序
/**demo.c**/
#include <pthread.h>

void* thread_f(void * i){      
//为了能让cpu可以把鸡蛋烤熟,必须确保你的程序是cpu密集型,不要有任何io操作
//我这里可是连printf语句都没有的。
    while(1){}    
    return NULL;
}

int main(int argc,char* argv[]){
    double count = 0;
    pthread_t t0;
    pthread_t t1;
    pthread_t t2;
    pthread_t t3;

    if(pthread_create(&t0, NULL, thread_f, NULL) == -1){
        puts("fail to create pthread t0");
        return 0;
    }

    if(pthread_create(&t1, NULL, thread_f, NULL) == -1){
        puts("fail to create pthread t1");
        return 0;
    }
  if(pthread_create(&t2, NULL, thread_f, NULL) == -1){
        puts("fail to create pthread t2");
        return 0;
    }

    if(pthread_create(&t3, NULL, thread_f, NULL) == -1){
        puts("fail to create pthread t3");
        return 0;
    }
    int ret = pthread_join(t0, NULL);
	return 0;
}

我当前主机是4核4线程的处理器,所以这里我是启动了4个线程去执行一段cpu密集型操作。如果没有isolcpus=0的限制,这个程序可以把4个核全部跑满。接下来编译demo.c

$ gcc demo.c -pthread -o demo
2、 运行用cpu烤鸡蛋的程序并验证结果
$ ./demo &
[1] 10451

然后使用mpstat命令查看所有cpu使用情况

$ mpstat -P ALL 4
Linux 3.10.0+ (localhost) 	20190926_mips64_	(4 CPU)

174557秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
174601秒  all   74.56    0.00    0.44    0.00    0.00    0.06    0.00    0.00    0.00   24.94
1746010    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
1746011   98.75    0.00    1.25    0.00    0.00    0.00    0.00    0.00    0.00    0.00
1746012   99.75    0.00    0.25    0.00    0.00    0.00    0.00    0.00    0.00    0.00
1746013   99.75    0.00    0.25    0.00    0.00    0.00    0.00    0.00    0.00    0.00

  可以看到,当期主机是4个处理器。上面的demo程序启动4个cpu密集型线程,理论上可以把4个处理器全部跑满,当是看上面的idle列,cpu1、cpu2和cpu3都已经为0,说明已经满负荷工作,而cpu0却还是idle 100,它已经被内核处理器调度策略排除运算了。也就说明上面的isolcpus=0设置成功。

注意.:如果你的机器没有mpstat工具,需要执行如下命令即可

$ yum install -y sysstat

二、设置程序demo独占处理器CPU0

  如何把一个进程或线程绑定(亲和)到固定的处理器,方法很多,可以在代码里设定,可以在程序启动时或启动后设定。

代码里设置的方法:
	int sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask); //设定某个进程的CPU亲和度
	int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset);//设定某个线程的CPU亲和度
命令行的设置方法有两种(使用taskset):

方法1、运行时指定:
     taskset < cpu列表 > [命令]
     例如:我想把demo应用运行在cpu0核上,那么命令是
             taskset -c cpu0 demo

方法2、运行后指定:
     taskset < cpu列表 > [PID]
    例如:demo程序已经在运行且pid为7013。那么我要设置此进程只能运行在cpu0核上。命令如下
             taskset -c cpu0 7013
注意.:在龙芯平台上,运行后的taskset无效。

我们使用运行时指定方式

$ taskset -c 0 ./demo &
[2] 11863

然后再次使用mpstat查看cpu占用率

]$  mpstat -P ALL 4
Linux 3.10.0+ (localhost) 	20190926_mips64_	(4 CPU)

180447秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
180451秒  all   29.12    0.00    0.38    0.00    0.00    0.00    0.00    0.00    0.00   70.51
1804510  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
1804511    0.50    0.00    0.50    0.00    0.00    0.00    0.00    0.00    0.00   99.00
1804512    9.05    0.00    0.75    0.00    0.00    0.00    0.00    0.00    0.00   90.20
1804513    6.28    0.00    0.50    0.00    0.00    0.00    0.00    0.00    0.00   93.22

  看到没?此时cpu0已经满负荷工作了(demo进程里的4个线程都运行在了cpu0上)。其他cpu1-cpu3却悠闲的很呢。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海棠花败

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值