• linux下把进程/线程绑定到指定cpu核上


    1、使用taskset指令

    1)获取进程pid

    [root@CENTOS57 eq]# ps aux | grep led
    root       9240  0.0  0.0   6324   376 pts/0    S    07:40   0:00 ./ledThread
    root       9242  0.0  0.0 112660   968 pts/0    S+   07:40   0:00 grep --color=auto led

    2)查看进程当前运行在哪个cpu核上

    p参数查看进程的绑定cpu核。

    [root@CENTOS57 eq]# taskset -p 9240
    pid 9240's current affinity mask: 2

    显示的十进制数字2转换为2进制为10,每个1对应一个cpu,所以进程运行在第2个cpu核上。

    3)指定进程运行在cpu3核上

    pc参数绑定cpu核。

    [root@CENTOS57 eq]# taskset -pc 3 9240
    pid 9240's current affinity list: 2
    pid 9240's new affinity list: 3
    
    [root@CENTOS57 eq]# taskset -p 9240
    pid 9240's current affinity mask: 8

    cpu的标号是从0开始的,所以cpu3表示第4个cpu(第一个cpu的标号是0)。

    至此,就把应用程序绑定到了cpu3上运行

    4)启动程序时绑定cpu核

    #启动时绑定到第二个cpu1
    [root@CENTOS57 eq]# taskset -c 1 ./ledall &
    [1] 3011
    
    #查看确认绑定情况
    [root@CENTOS57 eq]# taskset -p 3011
    pid 3011's current affinity mask: 2

    2、使用sched_setaffinity系统调用

    sched_setaffinity可以将某个进程绑定到一个特定的CPU。

    注意:在使用时,需要添加下面宏与头文件,并且顺序不可以颠倒。

    #define _GNU_SOURCE    
    #include <sched.h>
    
    cpu_set_t mask;
    CPU_ZERO(&mask);    //置空
    CPU_SET(n,&mask);   //设置亲和力值,绑定cpu核到(n)核上

    /* 设置进程号为pid的进程运行在mask所设定的CPU上 * 第二个参数cpusetsize是mask所指定的数的长度 * 通常设定为sizeof(cpu_set_t) * 如果pid的值为0,则表示指定的是当前进程 */ int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask); int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask); /* 获得pid所指示的进程的CPU位掩码,并将该掩码返回到mask所指向的结构中
    */

    例子1:pthread线程内部绑核

    #include<stdlib.h>
    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/sysinfo.h>
    #include<unistd.h>
    
    #define _GNU_SOURCE
    #include<sched.h>
    #include<ctype.h>
    #include<string.h>
    #include<pthread.h>
    #define THREAD_MAX_NUM 200  //1个CPU内的最多进程数
    
    int num=0;  //cpu中核数
    void* threadFun(void* arg)  //arg  传递线程标号(自己定义)
    {
        cpu_set_t mask;  //CPU核的掩码mask
        cpu_set_t get;   //获取cpu掩码
        int *a = (int *)arg; 
        int i;
    
        printf("the thread is:%d
    ",*a);  //显示是第几个线程
        CPU_ZERO(&mask);    //置空
        CPU_SET(*a,&mask);   //设置亲和力值,绑定cpu核到(*a)核上
        if (sched_setaffinity(0, sizeof(mask), &mask) == -1)//设置线程CPU亲和力
        {
            printf("warning: could not set CPU affinity 
    ");
        }
    
        CPU_ZERO(&get);
        if (sched_getaffinity(0, sizeof(get), &get) == -1)//获取线程CPU亲和力
        {
             printf("warning: cound not get thread affinity, continuing...
    ");
        }
        for (i = 0; i < num; i++)
        {
            if (CPU_ISSET(i, &get))//判断线程与哪个CPU有亲和力
            {
              printf("this thread %d is running processor : %d
    ", i,i);
            }
        }
    
       return NULL;
    }
    
    int main(int argc, char* argv[])
    {
       int tid[THREAD_MAX_NUM];
       int i;
       pthread_t thread[THREAD_MAX_NUM];
    num
    = sysconf(_SC_NPROCESSORS_CONF); //获取核数for(i=0;i<num;i++) { tid[i] = i; //每个线程必须有个tid[i] pthread_create(&thread[i],NULL,threadFun,(void*)&tid[i]); } for(i=0; i< num; i++) { pthread_join(thread[i],NULL);//等待所有的线程结束,线程为死循环所以CTRL+C结束 } return 0; }

     例子2:main主线程绑核

    #define _GNU_SOURCE             /* See feature_test_macros(7) */
    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sched.h>
    #include <pthread.h>
     
    void* testfunc(void* t) {
      while(1);
      return NULL; 
    }
     
    int main()
    {
      cpu_set_t mask;
      printf("pid=%d
    ", getpid());
      CPU_ZERO(&mask);
      CPU_SET(0, &mask);//将cpu0绑定
      sched_setaffinity(0, sizeof(cpu_set_t), &mask) ;
      
      pthread_t tid1;//创建线程1
      if (pthread_create(&tid1, NULL, (void *)testfunc, NULL) != 0) 
      {      
        fprintf(stderr, "thread create failed
    ");
        return -1;   
      }
      pthread_join(tid1, NULL);
      return 0;
    }

    例子3:main主函数内部绑线程核

    #define _GNU_SOURCE             /* See feature_test_macros(7) */
    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sched.h>
    #include <pthread.h>
     
    void* testfunc(void* t) {
      int i = 3;
      while(i) {
         sleep(5);
         printf("tid=%d,cpu=%d
    ",pthread_self(), sched_getcpu());
         i--;
      }return NULL; 
    }
     
    int main()
    {
      cpu_set_t mask;
      printf("pid=%d
    ", getpid());
      CPU_ZERO(&mask);
      
      pthread_t tid1;
      if (pthread_create(&tid1, NULL, (void *)testfunc, NULL) != 0) 
      {      
        fprintf(stderr, "thread create failed
    ");
        return -1;   
      }
      pthread_t tid2;
      if (pthread_create(&tid2, NULL, (void *)testfunc, NULL) != 0) 
      {      
        fprintf(stderr, "thread create failed
    ");
        return -1;   
      } 
      printf("tid1=%d,tid2=%d
    ", tid1,tid2);
     
      CPU_SET(0, &mask);//绑定cpu0,线程绑定
      pthread_setaffinity_np(tid1, sizeof(cpu_set_t), &mask) ;
      
      //清除之前设置,重新设置绑定cpu3
      CPU_ZERO(&mask);
      CPU_SET(3, &mask);
      pthread_setaffinity_np(tid2, sizeof(cpu_set_t), &mask) ;
      
      pthread_join(tid1, NULL);
      pthread_join(tid1, NULL);
      return 0;
    }

    参考引用:

    https://blog.csdn.net/guotianqing/article/details/80958281

  • 相关阅读:
    Istio安装配置及使用
    Istio介绍
    Rancher管理k8s集群
    EFK部署
    常见日志收集方案及相关组件
    Prometheus Pushgateway
    Prometheus监控拓展
    Prometheus PromQL语法
    开始新工作了
    SpringBlade 新系统 运行
  • 原文地址:https://www.cnblogs.com/ggzhangxiaochao/p/13858406.html
Copyright © 2020-2023  润新知