cpu亲和性(affinity)用于绑定到固定的CPU上。主要有以下函数。
int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t*mask);//进程绑定函数 int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset);//线程绑定函数 void CPU_ZERO (cpu_set_t *set) /这个宏对 CPU 集 set 进行初始化,将其设置为空集。/ void CPU_SET (int cpu, cpu_set_t *set) /这个宏将 指定的 cpu 加入 CPU 集 set 中/ void CPU_CLR (int cpu, cpu_set_t *set) /这个宏将 指定的 cpu 从 CPU 集 set 中删除。/ int CPU_ISSET (int cpu, const cpu_set_t *set)
/如果 cpu 是 CPU 集 set 的一员,这个宏就返回一个非零值(true),否则就返回零(false)。/
int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset);
int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset);
为了尽可能地降低多线程间的耦合性以提高速度,我们让不同CPU核心执行不同的线程。下面的程序可以指定哪个(些)核心去执行某个线程,主要部分是:
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(i, &mask);
pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask);
mask可以理解为一个集合,第2行清空mask,第三行把CPUi放入mask,还可以把更多CPUi放入mask。
假如这段代码在函数fac中,pthread_self()用于获取fac的线程ID,pthread_setaffinity_np把该ID与mask绑定,这样mask中的一个或多个CPU核心就负责执行该线程。如形式2。
1. 形式1
#include <pthread.h>
#include <stdlib.h>
#include <sys/sysinfo.h>
#include <unistd.h>
#include <assert.h>
//统计CPU核心数量
int countCPU(){
//#include <sys/sysinfo.h>
//get_nprocs_conf();
//get_nprocs();
//#include <unistd.h>
//sysconf(_SC_NPROCESSORS_CONF);
return sysconf(_SC_NPROCESSORS_ONLN);
}
void *fun(){
while(1);
}
int main(int argc, char *argv[]){
int i, cpu_nums = countCPU();
cpu_set_t cpuset[cpu_nums];//cpuset[i]是负责执行某个线程的若干个CPU核
pthread_t Thread[cpu_nums];//存放线程ID,ID由函数pthread_create分配
for (i=0; i<cpu_nums; i++){
CPU_ZERO(cpuset+i);//清空cpuset[i]
CPU_SET(i, cpuset+i);//cpuset[i]中只放了一个CPU核,如果需要可以继续放
pthread_create(&Thread[i], NULL, fun, NULL);//创建线程
//参数1:线程ID 参数3:执行这个线程的若干个CPU核
assert(!pthread_setaffinity_np(Thread[i], sizeof(cpu_set_t), cpuset+i));
}
for(i = 0; i < cpu_nums; ++i)
pthread_join(Thread[i],NULL);
exit(EXIT_SUCCESS);
}
2. 形式2
#include <unistd.h>
#include <pthread.h>
#include <assert.h>
void *fun(void i){
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET((int *)i, &mask);
assert(!pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask));
while(1){
//Todo
}
}
int main (int argc, const char * argv[]){
int cpu_nums = sysconf(_SC_NPROCESSORS_CONF);
int i, tmp[cpu_nums];
pthread_t Thread[cpu_nums];
for(i = 0; i < cpu_nums; ++i){
tmp[i] = i%3;//这是一个参数,让fun函数被核i%3执行
pthread_create(&Thread[i], NULL, fun, &tmp[i]);
}
for(i = 0; i < cpu_nums; ++i)
pthread_join(Thread[i],NULL);
return 0;
}