將線程綁定到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上運行線程,其他核沒有