Linux编程之《进程/线程绑定CPU》

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

 

复制代码

  1 /************************************************
  2  * 该例程讲解了进程、线程绑定到固定的cpu核心上运行
  3  * 来提高程序运行效率
  4 ************************************************/
  5 #include 
  6 #ifndef __USE_GNU
  7 #define __USE_GNU   // 为了使用SET_SET()等宏定义,但unistd.h里面好像已经定义了
  8 #endif
  9 #include 
 10 #include 
 11 #include 
 12 #include 
 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& 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& 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& 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& 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*****\n");
131     unsigned int cpuNum = systemCPUNum();
132     printf("Current system has %u CPU(s)\n", cpuNum);
133 
134     std::vector runningCPUVector;
135     if (!currentProcessAffinity(runningCPUVector))
136     {
137         printf("Get current process was bound witch CPU failed\n");
138         return 1;
139     }
140 
141     for (auto& iter : runningCPUVector)
142     {
143         printf("Current process is running at %u CPU\n", iter);
144     }
145 
146     std::vector needBindCPUVector {0, 2};
147     if (!setCurrentProcessAffinity(needBindCPUVector))
148     {
149         printf("Current process bind CPU failed\n");
150         return 1;
151     }
152 
153     printf("Current process bind CPU success\n");
154 
155     runningCPUVector.clear();
156     if (!currentProcessAffinity(runningCPUVector))
157     {
158         printf("Get current process was bound witch CPU failed\n");
159         return 1;
160     }
161 
162     for (auto& iter : runningCPUVector)
163     {
164         printf("Current process is running at %u CPU\n", iter);
165     }
166 
167     printf("\n*****Thread bind CPU sample*****\n");
168     runningCPUVector.clear();
169     if (!currentThreadAffinity(runningCPUVector))
170     {
171         printf("Get current thread was bound witch CPU failed\n");
172         return 1;
173     }
174 
175     for (auto& iter : runningCPUVector)
176     {
177         printf("Thread %lu is running at %u CPU\n", 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\n");
185         return 1;
186     }
187 
188     printf("Thread %lu bind CPU success\n", pthread_self());
189 
190     runningCPUVector.clear();
191     if (!currentThreadAffinity(runningCPUVector))
192     {
193         printf("Get current thread was bound witch CPU failed\n");
194         return 1;
195     }
196 
197     for (auto& iter : runningCPUVector)
198     {
199         printf("Thread %lu is running at %u CPU\n", 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

欢迎关注技术公众号:架构师成长营

Linux编程之《进程/线程绑定CPU》_第1张图片

 

你可能感兴趣的:(架构设计)