Linux编程之《进程/线程绑定CPU》
转载自: http://www.cnblogs.com/highway-9/p/5494977.html
ntro
-----
通常我们在编写服务器代码时,可以通过将当前进程绑定到固定的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*****\n");
131 unsigned int cpuNum = systemCPUNum();
132 printf("Current system has %u CPU(s)\n", cpuNum);
133
134 std::vector<unsigned int> 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<unsigned int> 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
该例子的github地址:https://github.com/chxuan/samples/blob/master/BindCPU/BindCPU.cpp
兴趣是最好的老师,我的github地址:https://github.com/chxuan


浙公网安备 33010602011771号