首页 > C/C++ > Linux进程或线程绑定到CPU
2017
09-10

Linux进程或线程绑定到CPU

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

1、进程绑定到CPU

1)、创建线程

  1. #include <sched.h>  
  2. int sched_setaffinity(pid_t pid, size cpusetsize, const cpu_set_t *mask); 调用成功完成则返回零,其它值表示出错  
  3. 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

 

 

 

实例:

/*pthread_create*/

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <math.h>
  4. #define __USE_GNU
  5. #include <sched.h>
  6.  
  7. void WasteTime()
  8. {
  9.     int abc = 10000000;
  10.     while(abc–)
  11.     {
  12.         int tmp = 10000*10000;
  13.     }
  14.     sleep(1);
  15.  
  16. }
  17.  
  18. int main(int argc, char **argv)
  19. {
  20.     cpu_set_t mask;
  21.     while(1)
  22.     {
  23.  
  24.         CPU_ZERO(&mask);
  25.         CPU_SET(0, &mask);
  26.         if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {
  27.             perror("sched_setaffinity");
  28.         }
  29.         WasteTime();
  30.  
  31.         CPU_ZERO(&mask);
  32.         CPU_SET(1, &mask);
  33.         if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {
  34.             perror("sched_setaffinity");
  35.         }
  36.         WasteTime();
  37.     
  38.         CPU_ZERO(&mask);
  39.         CPU_SET(2, &mask);
  40.         if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {
  41.             perror("sched_setaffinity");
  42.         }
  43.         WasteTime();
  44.     
  45.         CPU_ZERO(&mask);
  46.         CPU_SET(3, &mask);
  47.         if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {
  48.             perror("sched_setaffinity");
  49.         }
  50.         WasteTime();
  51.     }

 

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

Linux进程或线程绑定到CPU - 第1张  | 刘建广学习笔记

 

 

2)、线程绑定到CPU

  1. #include <pthread.h>  
  2. int pthread_join(thread_t tid, void **status); 调用成功完成则返回零,其它值表示出错  

该函数会一直阻塞调用线程,直到指定的线程终止。

指定的线程必须位于当前的进程中,而且不得是分离线程。如果status不为NULL时,则在pthread_join()成功返回时,指定线程的退出状态会通过它返回。
如果多个线程等待同一个线程终止,则所有等待线程将一直等到目标线程终止。然后,一个等待线程成功返回。其余的等待线程将失败并返回 ESRCH 错误。
在pthread_join()返回之后,应用程序可回收与已终止线程关联的任何数据存储空间。

 

 

实例:

/*pthread_join*/

  1. #include <stdio.h>
  2. #include <math.h>
  3. #define __USE_GNU
  4. #include <pthread.h>
  5. #include <unistd.h>
  6.  
  7. void WasteTime()
  8. {
  9.     int abc = 10000000;
  10.     while(abc–)
  11.     {
  12.         int tmp = 10000*10000;
  13.     }
  14.     sleep(1);
  15.  
  16. }
  17.  
  18. void *thread_func(void *param)
  19. {
  20.     cpu_set_t mask;
  21.     while(1)
  22.     {
  23.         CPU_ZERO(&mask);
  24.         CPU_SET(1, &mask);
  25.  
  26.         if (pthread_setaffinity_np(pthread_self(), sizeof(mask),
  27.             &mask) < 0) {
  28.             perror("pthread_setaffinity_np");
  29.         }
  30.  
  31.         WasteTime();
  32.  
  33.         CPU_ZERO(&mask);
  34.         CPU_SET(2, &mask);
  35.         if (pthread_setaffinity_np(pthread_self(), sizeof(mask),
  36.             &mask) < 0) {
  37.             perror("pthread_setaffinity_np");
  38.         }
  39.  
  40.         WasteTime();
  41.     }
  42. }
  43.  
  44. void *thread_func1(void *param)
  45. {
  46.     cpu_set_t mask;
  47.     while(1)
  48.     {
  49.         CPU_ZERO(&mask);
  50.         CPU_SET(3, &mask);
  51.  
  52.         if (pthread_setaffinity_np(pthread_self(), sizeof(mask),
  53.             &mask) < 0) {
  54.             perror("pthread_setaffinity_np");
  55.         }
  56.  
  57.         WasteTime();
  58.  
  59.         CPU_ZERO(&mask);
  60.         CPU_SET(4, &mask);
  61.         if (pthread_setaffinity_np(pthread_self(), sizeof(mask),
  62.             &mask) < 0) {
  63.             perror("pthread_setaffinity_np");
  64.         }
  65.  
  66.         WasteTime();
  67.     }
  68. }
  69.  
  70. int main(int argc, char *argv[])
  71. {
  72.     cpu_set_t mask;
  73.     CPU_ZERO(&mask);
  74.     CPU_SET(0, &mask);
  75.     if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {
  76.         perror("sched_setaffinity");
  77.     }
  78.  
  79.     pthread_t my_thread;
  80.  
  81.     if (pthread_create(&my_thread, NULL, thread_func,
  82.         NULL) != 0) {
  83.         perror("pthread_create");
  84.     }
  85.     if (pthread_create(&my_thread, NULL, thread_func1,
  86.         NULL) != 0) {
  87.         perror("pthread_create");
  88.     }
  89.     while(1) { WasteTime(); }
  90.     pthread_exit(NULL);
  91.  
  92. }

 

 

 

 

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

Linux进程或线程绑定到CPU - 第2张  | 刘建广学习笔记

最后编辑:
作者:liujg
真实-不弄虚,不做假,做自己,不违心; 踏实-不浮躁,不盲从,不急功,不近利; 实学-不投机,不取巧,勤于学,精于业。