zoukankan      html  css  js  c++  java
  • Linux编程之《进程/线程绑定CPU》

    Intro
    -----

    通常我们在编写服务器代码时,可以通过将当前进程绑定到固定的CPU核心或者线程绑定到固定的CPU核心来提高系统调度程序的效率来提高程序执行的效率,下面将完整代码贴上。

      1 /************************************************
      2  * 该例程讲解了进程、线程绑定到固定的cpu核心上运行
      3  * 来提高程序运行效率
      4 ************************************************/
      5 #include <unistd.h>
      6 #ifndef __USE_GNU
      7 #define __USE_GNU   // 为了使用SET_SET()等宏定义,但unistd.h里面好像已经定义了
      8 #endif
      9 #include <sched.h>
     10 #include <pthread.h>
     11 #include <stdio.h>
     12 #include <vector>
     13 
     14 unsigned int systemCPUNum()
     15 {
     16     // _SC_NPROCESSORS_CONF的值为CPU个数,基于0开始编号
     17     return sysconf(_SC_NPROCESSORS_CONF);
     18 }
     19 
     20 bool currentProcessAffinity(std::vector<unsigned int>& runningCPUVector)
     21 {
     22     cpu_set_t cpuSet;
     23 
     24     // 清空一个CPU集合
     25     CPU_ZERO(&cpuSet);
     26 
     27     // 得到指定进程ID绑定到哪个CPU
     28     int ret = sched_getaffinity(0, // 0代表当前进程
     29                                sizeof(cpuSet),
     30                                &cpuSet);
     31     if (ret < 0)
     32     {
     33         return false;
     34     }
     35 
     36     unsigned int cpuNum = systemCPUNum();
     37     runningCPUVector.clear();
     38     for (unsigned int i = 0; i < cpuNum; ++i)
     39     {
     40         // 检查一个CPU号是否在一个集合中
     41         if (CPU_ISSET(i, &cpuSet))
     42         {
     43             runningCPUVector.push_back(i);
     44         }
     45     }
     46 
     47     return true;
     48 }
     49 
     50 bool setCurrentProcessAffinity(const std::vector<unsigned int>& needBindCPUVector)
     51 {
     52     cpu_set_t cpuSet;
     53 
     54     // 清空一个CPU集合
     55     CPU_ZERO(&cpuSet);
     56     
     57     for (auto& iter : needBindCPUVector)
     58     {
     59         CPU_SET(iter, &cpuSet);
     60     }
     61 
     62     // 将指定进程ID绑定到CPU
     63     int ret = sched_setaffinity(0, // 0代表当前进程
     64                                sizeof(cpuSet),
     65                                &cpuSet);
     66     if (ret < 0)
     67     {
     68         return false;
     69     }
     70 
     71     return true;
     72 }
     73 
     74 bool currentThreadAffinity(std::vector<unsigned int>& runningCPUVector)
     75 {
     76     cpu_set_t cpuSet;
     77 
     78     // 清空一个CPU集合
     79     CPU_ZERO(&cpuSet);
     80 
     81     // 得到指定线程ID绑定到哪个CPU
     82     int ret = pthread_getaffinity_np(pthread_self(),
     83                                      sizeof(cpuSet),
     84                                      &cpuSet);
     85     if (ret < 0)
     86     {
     87         return false;
     88     }
     89 
     90     unsigned int cpuNum = systemCPUNum();
     91     runningCPUVector.clear();
     92     for (unsigned int i = 0; i < cpuNum; ++i)
     93     {
     94         // 检查一个CPU号是否在一个集合中
     95         if (CPU_ISSET(i, &cpuSet))
     96         {
     97             runningCPUVector.push_back(i);
     98         }
     99     }
    100 
    101     return true;
    102 }
    103 
    104 bool setCurrentThreadAffinity(const std::vector<unsigned int>& needBindCPUVector)
    105 {
    106     cpu_set_t cpuSet;
    107 
    108     // 清空一个CPU集合
    109     CPU_ZERO(&cpuSet);
    110     
    111     for (auto& iter : needBindCPUVector)
    112     {
    113         CPU_SET(iter, &cpuSet);
    114     }
    115 
    116     // 将指定线程ID绑定到CPU
    117     int ret = pthread_setaffinity_np(pthread_self(),
    118                                      sizeof(cpuSet),
    119                                      &cpuSet);
    120     if (ret < 0)
    121     {
    122         return false;
    123     }
    124 
    125     return true;
    126 }
    127 
    128 int main()
    129 {
    130     printf("*****Process bind CPU sample*****
    ");
    131     unsigned int cpuNum = systemCPUNum();
    132     printf("Current system has %u CPU(s)
    ", cpuNum);
    133 
    134     std::vector<unsigned int> runningCPUVector;
    135     if (!currentProcessAffinity(runningCPUVector))
    136     {
    137         printf("Get current process was bound witch CPU failed
    ");
    138         return 1;
    139     }
    140 
    141     for (auto& iter : runningCPUVector)
    142     {
    143         printf("Current process is running at %u CPU
    ", iter);
    144     }
    145 
    146     std::vector<unsigned int> needBindCPUVector {0, 2};
    147     if (!setCurrentProcessAffinity(needBindCPUVector))
    148     {
    149         printf("Current process bind CPU failed
    ");
    150         return 1;
    151     }
    152 
    153     printf("Current process bind CPU success
    ");
    154 
    155     runningCPUVector.clear();
    156     if (!currentProcessAffinity(runningCPUVector))
    157     {
    158         printf("Get current process was bound witch CPU failed
    ");
    159         return 1;
    160     }
    161 
    162     for (auto& iter : runningCPUVector)
    163     {
    164         printf("Current process is running at %u CPU
    ", iter);
    165     }
    166 
    167     printf("
    *****Thread bind CPU sample*****
    ");
    168     runningCPUVector.clear();
    169     if (!currentThreadAffinity(runningCPUVector))
    170     {
    171         printf("Get current thread was bound witch CPU failed
    ");
    172         return 1;
    173     }
    174 
    175     for (auto& iter : runningCPUVector)
    176     {
    177         printf("Thread %lu is running at %u CPU
    ", pthread_self(), iter);
    178     }
    179 
    180     needBindCPUVector.clear();
    181     needBindCPUVector.push_back(1);
    182     if (!setCurrentThreadAffinity(needBindCPUVector))
    183     {
    184         printf("Current thread bind CPU failed
    ");
    185         return 1;
    186     }
    187 
    188     printf("Thread %lu bind CPU success
    ", pthread_self());
    189 
    190     runningCPUVector.clear();
    191     if (!currentThreadAffinity(runningCPUVector))
    192     {
    193         printf("Get current thread was bound witch CPU failed
    ");
    194         return 1;
    195     }
    196 
    197     for (auto& iter : runningCPUVector)
    198     {
    199         printf("Thread %lu is running at %u CPU
    ", pthread_self(), iter);
    200     }
    201 
    202     return 0;
    203 }

    程序执行的输出结果:
    *****Process bind CPU sample*****
    Current system has 4 CPU(s)
    Current process is running at 0 CPU
    Current process is running at 1 CPU
    Current process is running at 2 CPU
    Current process is running at 3 CPU
    Current process bind CPU success
    Current process is running at 0 CPU
    Current process is running at 2 CPU

    *****Thread bind CPU sample*****
    Thread 139871129114432 is running at 0 CPU
    Thread 139871129114432 is running at 2 CPU
    Thread 139871129114432 bind CPU success
    Thread 139871129114432 is running at 1 CPU

    该例子的github地址:https://github.com/chxuan/samples/blob/master/BindCPU/BindCPU.cpp

  • 相关阅读:
    蓝书·目录
    CSPs-2019·爆零游记
    [原创题目]Uncomplicated Card Recreation
    珂朵莉树(ODT)
    CF407B 「Long Path」
    Manacher(马拉车)
    CSPs-2020 游记
    STM32CubeMX的使用(以点亮闪烁LED为例)
    基于STM32CubeMX的定时器设置
    STM32的中断系统和外部中断(基于STM32CubeMX开发)
  • 原文地址:https://www.cnblogs.com/highway-9/p/5494977.html
Copyright © 2011-2022 走看看