CPU親合力就是指在Linux系統中能夠將一個或多個進程綁定到一個或多個處理器上運行.
一個進程的CPU親合力掩碼決定了該進程將在哪個或哪幾個CPU上運行.在一個多處理器系統中,設置CPU親合力的掩碼可能會獲得更好的性能.
一個CPU的親合力掩碼用一個cpu_set_t結構體來表示一個CPU集合,下面的幾個宏分別對這個掩碼集進行操作:
·CPU_ZERO() 清空一個集合
·CPU_SET()與CPU_CLR()分別對將一個給定的CPU號加到一個集合或者從一個集合中去掉.
·CPU_ISSET()檢查一個CPU號是否在這個集合中.
下面兩個函數就是用來設置獲取線程CPU親和力狀態:
·sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)
該函數設置進程為pid的這個進程,讓它運行在mask所設定的CPU上.如果pid的值為0,則表示指定的是當前進程,使當前進程運行在mask所設定的那些CPU上.第二個參數cpusetsize是mask所指定的數的長度.通常設定為sizeof(cpu_set_t).如果當前pid所指定的進程此時沒有運行在mask所指定的任意一個CPU上,則該指定的進程會從其它CPU上遷移到mask的指定的一個CPU上運行.
·sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)
該函數獲得pid所指示的進程的CPU位掩碼,並將該掩碼返回到mask所指向的結構中.即獲得指定pid當前可以運行在哪些CPU上.同樣,如果pid的值為0.也表示的是當前進程
-
cpu_set_t的定義
-
-
-
-
typedef unsigned long int __cpu_mask;
-
-
-
typedef struct
-
{
-
__cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS];
-
} cpu_set_t;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
測試代碼:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
int num=0; //cpu中核數
-
void* threadFun(void* arg) //arg 傳遞線程標號(自己定義)
-
{
-
cpu_set_t mask; //CPU核的集合
-
cpu_set_t get; //獲取在集合中的CPU
-
int *a = (int *)arg;
-
printf("the a is:%d\n",*a); //顯示是第幾個線程
-
CPU_ZERO(&mask); //置空
-
CPU_SET(*a,&mask); //設置親和力值
-
if (sched_setaffinity(0, sizeof(mask), &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: cound not get thread affinity, continuing...\n");
-
}
-
int i;
-
for (i = 0; i < num; i++)
-
{
-
if (CPU_ISSET(i, &get))//判斷線程與哪個CPU有親和力
-
{
-
printf("this thread %d is running processor : %d\n", i,i);
-
}
-
}
-
}
-
-
return NULL;
-
}
-
-
int main(int argc, char* argv[])
-
{
-
num = sysconf(_SC_NPROCESSORS_CONF); //獲取核數
-
pthread_t thread[THREAD_MAX_NUM];
-
printf("system has %i processor(s). \n", num);
-
int tid[THREAD_MAX_NUM];
-
int i;
-
for(i=0;i<num;i++)
-
{
-
tid[i] = i; //每個線程必須有個tid[i]
-
pthread_create(&thread[ 0],NULL,threadFun,(void*)&tid[i]);
-
}
-
for(i=0; i< num; i++)
-
{
-
pthread_join(thread[i], NULL);//等待所有的線程結束,線程為死循環所以CTRL+C結束
-
}
-
return 0;
-
}
編譯命令:gcc bind.c -o bind -lpthread
執行:./bind
輸出結果:略
特別注意:
#define __USE_GNU不要寫成#define _USE_GNU
#include<pthread.h>必須寫在#define __USE_GNU之后,否則編譯會報錯
查看你的線程情況可以在執行時在另一個窗口使用top -H來查看線程的情況,查看各個核上的情況請使用top命令然后按數字“1”來查看。