1、使用taskset指令
1)獲取進程pid
[root@CENTOS57 eq]# ps aux | grep led root 9240 0.0 0.0 6324 376 pts/0 S 07:40 0:00 ./ledThread root 9242 0.0 0.0 112660 968 pts/0 S+ 07:40 0:00 grep --color=auto led
2)查看進程當前運行在哪個cpu核上
p參數查看進程的綁定cpu核。
[root@CENTOS57 eq]# taskset -p 9240 pid 9240's current affinity mask: 2
顯示的十進制數字2轉換為2進制為10,每個1對應一個cpu,所以進程運行在第2個cpu核上。
3)指定進程運行在cpu3核上
pc參數綁定cpu核。
[root@CENTOS57 eq]# taskset -pc 3 9240 pid 9240's current affinity list: 2 pid 9240's new affinity list: 3 [root@CENTOS57 eq]# taskset -p 9240 pid 9240's current affinity mask: 8
cpu的標號是從0開始的,所以cpu3表示第4個cpu(第一個cpu的標號是0)。
至此,就把應用程序綁定到了cpu3上運行
4)啟動程序時綁定cpu核
#啟動時綁定到第二個cpu1 [root@CENTOS57 eq]# taskset -c 1 ./ledall & [1] 3011 #查看確認綁定情況 [root@CENTOS57 eq]# taskset -p 3011 pid 3011's current affinity mask: 2
2、使用sched_setaffinity系統調用
sched_setaffinity可以將某個進程綁定到一個特定的CPU。
注意:在使用時,需要添加下面宏與頭文件,並且順序不可以顛倒。
#define _GNU_SOURCE #include <sched.h>
cpu_set_t mask;
CPU_ZERO(&mask); //置空 CPU_SET(n,&mask); //設置親和力值,綁定cpu核到(n)核上
/* 設置進程號為pid的進程運行在mask所設定的CPU上 * 第二個參數cpusetsize是mask所指定的數的長度 * 通常設定為sizeof(cpu_set_t) * 如果pid的值為0,則表示指定的是當前進程 */ int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask); int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask); /* 獲得pid所指示的進程的CPU位掩碼,並將該掩碼返回到mask所指向的結構中
*/
例子1:pthread線程內部綁核
#include<stdlib.h> #include<stdio.h> #include<sys/types.h> #include<sys/sysinfo.h> #include<unistd.h> #define _GNU_SOURCE #include<sched.h> #include<ctype.h> #include<string.h> #include<pthread.h> #define THREAD_MAX_NUM 200 //1個CPU內的最多進程數 int num=0; //cpu中核數 void* threadFun(void* arg) //arg 傳遞線程標號(自己定義) { cpu_set_t mask; //CPU核的掩碼mask cpu_set_t get; //獲取cpu掩碼 int *a = (int *)arg; int i; printf("the thread is:%d\n",*a); //顯示是第幾個線程 CPU_ZERO(&mask); //置空 CPU_SET(*a,&mask); //設置親和力值,綁定cpu核到(*a)核上 if (sched_setaffinity(0, sizeof(mask), &mask) == -1)//設置線程CPU親和力 { printf("warning: could not set CPU affinity \n"); } CPU_ZERO(&get); if (sched_getaffinity(0, sizeof(get), &get) == -1)//獲取線程CPU親和力 { printf("warning: cound not get thread affinity, continuing...\n"); } 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[]) { int tid[THREAD_MAX_NUM]; int i; pthread_t thread[THREAD_MAX_NUM];
num = sysconf(_SC_NPROCESSORS_CONF); //獲取核數for(i=0;i<num;i++) { tid[i] = i; //每個線程必須有個tid[i] pthread_create(&thread[i],NULL,threadFun,(void*)&tid[i]); } for(i=0; i< num; i++) { pthread_join(thread[i],NULL);//等待所有的線程結束,線程為死循環所以CTRL+C結束 } return 0; }
例子2:main主線程綁核
#define _GNU_SOURCE /* See feature_test_macros(7) */ #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <sched.h> #include <pthread.h> void* testfunc(void* t) { while(1); return NULL; } int main() { cpu_set_t mask; printf("pid=%d\n", getpid()); CPU_ZERO(&mask); CPU_SET(0, &mask);//將cpu0綁定 sched_setaffinity(0, sizeof(cpu_set_t), &mask) ; pthread_t tid1;//創建線程1 if (pthread_create(&tid1, NULL, (void *)testfunc, NULL) != 0) { fprintf(stderr, "thread create failed\n"); return -1; } pthread_join(tid1, NULL); return 0; }
例子3:main主函數內部綁線程核
#define _GNU_SOURCE /* See feature_test_macros(7) */ #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <sched.h> #include <pthread.h> void* testfunc(void* t) { int i = 3; while(i) { sleep(5); printf("tid=%d,cpu=%d\n",pthread_self(), sched_getcpu()); i--; }return NULL; } int main() { cpu_set_t mask; printf("pid=%d\n", getpid()); CPU_ZERO(&mask); pthread_t tid1; if (pthread_create(&tid1, NULL, (void *)testfunc, NULL) != 0) { fprintf(stderr, "thread create failed\n"); return -1; } pthread_t tid2; if (pthread_create(&tid2, NULL, (void *)testfunc, NULL) != 0) { fprintf(stderr, "thread create failed\n"); return -1; } printf("tid1=%d,tid2=%d\n", tid1,tid2); CPU_SET(0, &mask);//綁定cpu0,線程綁定 pthread_setaffinity_np(tid1, sizeof(cpu_set_t), &mask) ; //清除之前設置,重新設置綁定cpu3 CPU_ZERO(&mask); CPU_SET(3, &mask); pthread_setaffinity_np(tid2, sizeof(cpu_set_t), &mask) ; pthread_join(tid1, NULL); pthread_join(tid1, NULL); return 0; }
參考引用:
https://blog.csdn.net/guotianqing/article/details/80958281