【Linux下进程的CPU配置和线程绑定】( 二 )


显示的十六进制f转换为二进制为最低四个是1,每个1对应一个CPU,所以进程运行在4个CPU上 。
·指定进程10770运行在CPU0上:
注意,CPU的标号是从0开始的,所以cpu0表示第1个CPU(第一个CPU的标号是0) 。
至此,就把应用程序绑定到了CPU0上运行,查看如下:
·启动程序时绑定CPU:

【Linux下进程的CPU配置和线程绑定】

文章插图
例如启动时绑定到第二个CPU上,即CPU1:
使用系统调用
通过系统调用进行绑定,通过获取绑定关系 。注意这对方法是进程级别的绑定 。代码中指定cpu0和cpu3,我们可以通过top查看,两个CPU使用达到了100%,其他的CPU均不会(正常场景) 。
sched_setaffinity可以将某个进程绑定到一个特定的CPU 。
#define _GNU_SOURCE/* See feature_test_macros(7) */#include /* 设置进程号为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所指向的结构中 */
代码示例:
/**该程序演示了如何使用sched_setaffinity函数将线程绑定到特定的CPU核心上运行 。*程序首先创建了两个线程,然后使用sched_setaffinity函数将线程1绑定到CPU 0上,将线程2绑定到CPU 3上 。*运行时,可以通过查看输出的pid来确定程序的进程ID 。*然后,程序将CPU_ZERO宏应用于一个cpu_set_t类型的变量mask,以将其初始化为空集 。*接下来,程序将CPU_SET宏应用于mask,将CPU 0和CPU 3添加到集合中 。*最后,程序调用sched_setaffinity函数将mask应用于当前进程,将线程1绑定到CPU 0上,将线程2绑定到CPU 3上 。*线程创建成功后,程序使用pthread_join函数等待线程1和线程2的结束 。*/#define _GNU_SOURCE/* See feature_test_macros(7) */#include #include #include #include #include void* testfunc(void* t) {while(1);return NULL; }int main(){cpu_set_t mask; // 定义cpu_set_t类型的变量mask,用于存储CPU集合printf("pid=%d\n", getpid()); // 打印进程IDCPU_ZERO(&mask); // 将mask初始化为空集CPU_SET(0, &mask);//将cpu0绑定到mask中CPU_SET(3, &mask);//将cpu3绑定到mask中// 将mask应用于当前进程,绑定线程到指定的CPU核心sched_setaffinity(0, sizeof(cpu_set_t), &mask) ;pthread_t tid1;//创建线程1if (pthread_create(&tid1, NULL, (void *)testfunc, NULL) != 0) {fprintf(stderr, "thread create failed\n"); // 线程创建失败,打印错误信息return -1;}pthread_t tid2;//创建线程2if (pthread_create(&tid2, NULL, (void *)testfunc, NULL) != 0) {fprintf(stderr, "thread create failed\n"); // 线程创建失败,打印错误信息return -1;} pthread_join(tid1, NULL); // 等待线程1结束pthread_join(tid1, NULL); // 等待线程2结束return 0;}
执行结果如下图所示:
执行前:
执行后:
2 基于线程的CPU配置 2.1 线程绑定:使用函数np
线程绑定CPU核心的意义:
在多核CPU中合理的调度线程在各个核上运行可以获得更高的性能 。在多线程编程中,每个线程处理的任务优先级是不一样的,对于要求实时性比较高的线程或者是主线程,对于这种线程我们可以在创建线程时指定其绑定到某个CPU核上,以后这个核就专门处理该线程 。这样可以使得该线程的任务可以得到较快的处理,特别是和用户直接交互的任务,较短的响应时间可以提升用户的体验感 。
几个重要的宏操作: