转载

Linux进程或线程绑定到CPU

Linux 进程或线程绑定到 CPU

为了让程序拥有更好的性能,有时候需要将进程或线程绑定到特定的 CPU ,这样可以减少调度的开销和保护关键进程或线程。

进程绑定到 CPU

Linux 提供一个接口,可以将进程绑定到特定的 CPU

#include <sched.h>

int sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask);

int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);

参数

pid :进程的 id 号,如果 pid 0 ,则表示本进程

cpusetsize mask 的大小

mask :运行进程的 CPU ,可以通过以下函数操作 mask

#define CPU_SET(cpu, cpusetp) // 设置 cpu

#define CPU_CLR(cpu, cpusetp) // 删除 cpu

#define CPU_ISSET(cpu, cpusetp) // 判断 cpu

#define CPU_ZERO(cpusetp) // 初始化为 0

示例代码

#include <stdio.h> #include <unistd.h> #include <math.h> #include <sched.h> void WasteTime() {  int abc = 10000000;  while(abc--)  {   int tmp = 10000*10000;  }  sleep(1); } int main(int argc, char **argv) {  cpu_set_t mask;  while(1)  {   CPU_ZERO(&mask);   CPU_SET(0, &mask);    if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {    perror("sched_setaffinity");   }   WasteTime();   CPU_ZERO(&mask);   CPU_SET(1, &mask);    if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {    perror("sched_setaffinity");   }   WasteTime();   CPU_ZERO(&mask);   CPU_SET(2, &mask);    if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {    perror("sched_setaffinity");   }   WasteTime();   CPU_ZERO(&mask);   CPU_SET(3, &mask);    if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {    perror("sched_setaffinity");   }   WasteTime();  } } 

测试

编译之后运行程序,输入命令 top -p  进程 id ,输入 f ,输入 j ,输入回车,可以看到进程在 cpu0123 之间不停切换。

Linux进程或线程绑定到CPU

线程绑定到 CPU

不仅仅进程可以绑定到 CPU ,线程也可以。 Linux 提供一个接口,可以将线程绑定到特定的 CPU

#include <pthread.h>

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 之后,线程还是可以绑定到其他的 CPU 的,没有冲突。

示例代码

#include <stdio.h> #include <math.h> #include <pthread.h> #include <unistd.h> #include <sched.h> void WasteTime() {  int abc = 10000000;  while(abc--)  {   int tmp = 10000*10000;  }  sleep(1); } void *thread_func(void *param) {  cpu_set_t mask;  while(1)  {    CPU_ZERO(&mask);   CPU_SET(1, &mask);    if (pthread_setaffinity_np(pthread_self(), sizeof(mask),    &mask) < 0) {    perror("pthread_setaffinity_np");   }   WasteTime();    CPU_ZERO(&mask);   CPU_SET(2, &mask);    if (pthread_setaffinity_np(pthread_self(), sizeof(mask),    &mask) < 0) {    perror("pthread_setaffinity_np");   }   WasteTime();  } } void *thread_func1(void *param) {  cpu_set_t mask;  while(1)  {    CPU_ZERO(&mask);   CPU_SET(3, &mask);    if (pthread_setaffinity_np(pthread_self(), sizeof(mask),    &mask) < 0) {    perror("pthread_setaffinity_np");   }   WasteTime();    CPU_ZERO(&mask);   CPU_SET(4, &mask);    if (pthread_setaffinity_np(pthread_self(), sizeof(mask),    &mask) < 0) {    perror("pthread_setaffinity_np");   }   WasteTime();  } } int main(int argc, char *argv[]) {  cpu_set_t mask;   CPU_ZERO(&mask);  CPU_SET(0, &mask);   if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {   perror("sched_setaffinity");  }  pthread_t my_thread;  if (pthread_create(&my_thread, NULL, thread_func,   NULL) != 0) {   perror("pthread_create");  }  if (pthread_create(&my_thread, NULL, thread_func1,   NULL) != 0) {   perror("pthread_create");  }  while(1) { WasteTime(); }  pthread_exit(NULL); } 

测试

编译运行之后,输入命令 top -p  进程 id ,输入 f ,输入 j ,输入回车,输入 H ,可以看到主线程一直保持在 cpu0 ,一个线程在 cpu12 之前切换,另一个线程在 cpu34 之间切换。

Linux进程或线程绑定到CPU

正文到此结束
Loading...