使用 sched_setaffinity 将线程绑到CPU核上运行
linux 提供CPU調(diào)度函數(shù),可以將CPU某一個(gè)核和指定的線程綁定到一塊運(yùn)行。
這樣能夠充分利用CPU,且減少了不同CPU核之間的切換,尤其是在IO密集型壓力之下能夠提供較為友好的性能。
通過sched_setaffinity 設(shè)置 CPU 親和力的掩碼,從而將該線程或者進(jìn)程和指定的CPU綁定
一個(gè)CPU的親合力掩碼用一個(gè)cpu_set_t結(jié)構(gòu)體來表示一個(gè)CPU集合,下面的幾個(gè)宏分別對(duì)這個(gè)掩碼集進(jìn)行操作:
CPU_ZERO() 清空一個(gè)集合
CPU_SET()與CPU_CLR()分別對(duì)將一個(gè)給定的CPU號(hào)加到一個(gè)集合或者從一個(gè)集合中去掉.
CPU_ISSET()檢查一個(gè)CPU號(hào)是否在這個(gè)集合中
- 頭文件
sched.h sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)
該函數(shù)設(shè)置進(jìn)程為pid的這個(gè)進(jìn)程,讓它運(yùn)行在mask所設(shè)定的CPU上.- 如果pid的值為0,則表示指定的是當(dāng)前進(jìn)程,使當(dāng)前進(jìn)程運(yùn)行在mask所設(shè)定的那些CPU上.
- 第二個(gè)參數(shù)cpusetsize是mask所指定的數(shù)的長(zhǎng)度.通常設(shè)定為sizeof(cpu_set_t).如果當(dāng)前pid所指定的進(jìn)程此時(shí)沒有運(yùn)行在mask所指定的任意一個(gè)CPU上,則該指定的進(jìn)程會(huì)從其它CPU上遷移到mask的指定的一個(gè)CPU上運(yùn)行.
- mask 即用戶 通過
CPU_SET接口,線程ID 綁定刀片集合中的一個(gè)CPU上,使用mask來表示cpu集合中的CPU
- sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)
該函數(shù)獲得pid所指示的進(jìn)程的CPU位掩碼,并將該掩碼返回到mask所指向的結(jié)構(gòu)中.即獲得指定pid當(dāng)前可以運(yùn)行在哪些CPU上.同樣,如果pid的值為0.也表示的是當(dāng)前進(jìn)程
使用方式如下:
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <string.h>#define __USE_GNU
#include <sched.h>
#include <pthread.h>int num;void *thread_func1(void *arg) {cpu_set_t mask; //CPU核的集合cpu_set_t get; //獲取在集合中的CPUint *a = (int*)arg; printf("the a is:%d\n",*a); //顯示是第幾個(gè)線程CPU_ZERO(&mask); //置空CPU_SET(*a,&mask); // 將當(dāng)前線程和CPU綁定if(sched_setaffinity(0, sizeof(mask), &mask)) {printf("warning ! set affinity failed! \n"); } else {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))//判斷線程與哪個(gè)CPU有親和力{printf("this thread %d is running processor : %d\n", i,i);}}}}return NULL;
}void *thread_func2(void *arg) {cpu_set_t mask; //CPU核的集合cpu_set_t get; //獲取在集合中的CPUint *a = (int*)arg; printf("the a is:%d\n",*a); //顯示是第幾個(gè)線程CPU_ZERO(&mask); //置空CPU_SET(*a,&mask); // 將當(dāng)前線程和CPU綁定if(sched_setaffinity(0, sizeof(mask), &mask) == -1) {printf("warning ! set affinity failed! \n"); } else {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))//判斷線程與哪個(gè)CPU有親和力{printf("this thread %d is running processor : %d\n", i,i);}}}}return NULL;
}int main() {pthread_t t1;pthread_t t2;int t_1 = 0;int t_2 = 1;// 獲取CPU核數(shù)num = sysconf(_SC_NPROCESSORS_CONF);// 需要傳入t_1,t_2,來作為線程的參數(shù),用來核CPU核綁定pthread_create(&t1, NULL, (void *)thread_func1,&t_1);pthread_create(&t2, NULL, (void *)thread_func2,&t_2);pthread_join(t1, NULL);pthread_join(t2, NULL);printf("main thread end\n");return 0;
}
如果使用到pthread,則需要將pthread.h 放到sched.h之后,并在sched.h之前聲明#define __USE_GNU,
否則會(huì)出現(xiàn)undefined reference CPU_ZERO等錯(cuò)誤
編譯:
gcc sched_cpu.c -o sched_cpu -pthread
以上代碼將兩個(gè)線程分別綁定到0,1號(hào)CPU上
運(yùn)行后的CPU 效果圖如下:
總結(jié)
以上是生活随笔為你收集整理的使用 sched_setaffinity 将线程绑到CPU核上运行的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 天子多少钱啊?
- 下一篇: 关于 Rocksdb 性能分析 需要知