• c++ 线程绑定到cpu指定核心


    将线程绑定到cpu指定核心可以避免线程函数在多个核心上执行,从而减少线程间通信的开销,也方便查看负载,便于比较不同线程之间负载是否均衡。

    cpu的声明(变量类型)cpu_set_t

    绑定进程主要是通过三个函数,这三个函数都是在线程函数里面调用的

    CPU_ZERO(&cpu_size_t)  cpu初始化,将这个cpu置为空

    CPU_SET(int,cpu_size_t&)  int是cpu核的编号,这是一个设置具体哪个核的过程。专业名词叫亲和力,线程绑定核都是通过亲和力来完成的

    sched_setaffinity(int,sizeof(cpu_set_t),&cpu_set_t)将线程与cpu核绑定,具体绑定哪个核通过上一步的CPU_SET已经确定int为0时表示此线程函数
    #include <stdlib.h>
    #include <stdio.h>
    // #include <sys/types.h>
    // #include <sys/sysinfo.h>
    #include <unistd.h>
    
    #define __USE_GUN
    // #include <sched.h>
    // #include <ctype.h>
    #include <string.h>
    #include <pthread.h>
    #define THREAD_MAX_NUM 100// 1个cpu内最多进程数
    int num=0; //cpu中核数
    
    void* threadFun(void* arg)// arg传递线程标号,自己定义
    {
        //sleep(2);
        cpu_set_t mask;// cpu核的集合
        cpu_set_t get;// 获取在集合中的cpu
        int* a=(int*)arg;
        printf("this is: %d\n",*a);// 打印这是第几个线程
        CPU_ZERO(&mask);// 将集合置为空集
        CPU_SET(*a,&mask);// 设置亲和力值
        
        if(sched_setaffinity(0,sizeof(cpu_set_t),&mask)==-1)// 设置线程cpu亲和力
        {
            printf("warning: could not set CPU affinity, continuing...\n");
        }
        while(1)
        {
            CPU_ZERO(&get);
            if(sched_getaffinity(0,sizeof(get),&get)==-1)// 获取线程cpu亲和力
            {
                printf("warning: could not get thread affinity, continuing...\n");
            }
            for(int i=0;i<num;++i)
            {
                if(CPU_ISSET(i,&get))// 判断线程与哪个cpu有亲和力
                {
                    //printf("this thread %d is running processor: %d\n",i,i);
                    int a=1000000*1000000;
                }
            }
        }
        return NULL;
    }
    
    int main(void)
    {
        num=sysconf(_SC_NPROCESSORS_CONF);// 获取核数
        pthread_t thread[THREAD_MAX_NUM];
        printf("system has %i processor(s).\n",num);
        int tid[THREAD_MAX_NUM];
        for(int i=0;i<10;++i)
        {
            if(i%2==0)
            {
                tid[i]=i;// 每个线程必须有个tid[i]
                pthread_create(&thread[i],NULL,threadFun,(void*)&tid[i]);
            }
            //sleep(2);
        }
        for(int i=0;i<num;++i)
        {
            pthread_join(thread[i],NULL);
        }
        return 0;
    }

    注意线程库的选择,用c++自带的线程库<thread>是不可以的,这个库里的线程无法绑定到cpu核,必须使用<pthread.h>

    num=sysconf(_SC_NPROCESSORS_CONF);是获取该计算机的cpu有多少核,在头文件<unistd.h>中定义
    <pthread.h>中包含了<sched.h>所以不需要重复引用
    CPU_SET这些函数都是通过宏来实现的,通过操作cpu_set_t的补码,我没有去仔细研究,参考这个:https://blog.csdn.net/STN_LCD/article/details/78134574
    该程序的意思是0~9取偶数作为cpu核的id,将线程函数绑定在偶数核上
    在CMakeLists.txt文件中要加上set(CMAKE_CXX_FLAGS "${CAMKE_CXX_FLAGS} -std=c++11 -pthread")
    结果如下

     通过top查看详细信息

     接着按1查看cpu核详情

     cpu 0,2,4,6,8上运行线程,其他核没有

      

     
  • 相关阅读:
    Do You See Me? Ethical Considerations of the Homeless
    ELDER HOMELESSNESS WHY IS THIS AN ISSUE?
    Endoflife support is lacking for homeless people
    html内联框架
    html字体
    html块 div span
    html列表
    html表格
    SQL Server管理员专用连接的使用   作为一名DBA,经常会处理一些比较棘手的服务无响应问题,鉴于事态的严重性,多数DBA可能直接用“重启”大法,以便尽快的恢复生产环境的正常运转,但是多数情况
    如何配置最大工作线程数 (SQL Server Management Studio)
  • 原文地址:https://www.cnblogs.com/wangtianning1223/p/15919596.html
Copyright © 2020-2023  润新知