Linux CPU线程绑核

为了加快程序的运行速度和充分利用CPU资源,我们可以人为将不同线程绑定在不同的cup上,例如有两个线程A,B,其中A已经在CPU0上运行,并且CPU0上还有其他的任务,那么我们可以将线程B绑到CPU1上,这样就可以减轻CPU0的负担,从而充分利用多核CPU。原来是一个CPU做两件事,现在两个CPU同时做两个事,使效率更高。

看下下面的代码

cpp 复制代码
#define _GNU_SOURCE
#include <sched.h>      //这两个头文件是一起的
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
 
void *myfun(void *arg)
{
    cpu_set_t mask;
    cpu_set_t get;
  
    CPU_ZERO(&mask);
    CPU_SET(1, &mask);
    if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) 
    {
        fprintf(stderr, "set thread affinity failed\n");
    }
 
    CPU_ZERO(&get);
 
    if (pthread_getaffinity_np(pthread_self(), sizeof(get), &get) < 0) 
    {
        fprintf(stderr, "get thread affinity failed\n");
    }
    if (CPU_ISSET(1, &get)) 
    {
            printf("thread %lu is running in processor 1\n", (long unsigned)pthread_self());
    }
    pthread_exit(NULL);     //退出线程
}
 
int main(int argc, char *argv[])
{
    pthread_t tid;          //用来创建新的线程
    cpu_set_t mask;         //用来设置
    cpu_set_t get;          //用来获
 
    int num = sysconf(_SC_NPROCESSORS_CONF);    //获取CPU核数
    printf("system has %d processor(s)\n", num);
 
    if (pthread_create(&tid, NULL, (void *)myfun, NULL) != 0)    //创建线程  myfun为入口函数
    {
        fprintf(stderr, "thread create failed\n");
        return -1;
    }
    
    CPU_ZERO(&mask);            //初始化某个CPU集,设置为空
    CPU_SET(0, &mask);          //将某个CPU加入到这个CPU集合里,这里是,也可以理解为,绑定CPU,这里是CPU0
    if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0)       //pthread_self():获得线程自身ID
    {                                                                       //设置某一线程运行在某个CPU上
        fprintf(stderr, "set thread affinity failed\n");
    }
    
    CPU_ZERO(&get);
    
    if (pthread_getaffinity_np(pthread_self(), sizeof(get), &get) < 0) 
    {                                                                       //查看某一个CPU上有哪些线程
        fprintf(stderr, "get thread affinity failed\n");
    }
    if (CPU_ISSET(0, &get)) {                                               //判断某个CPU是不是在CPU集里,这里为CPU0
            printf("thread %lu is running in processor 0\n", (long unsigned)pthread_self());
    }
 
    pthread_join(tid, NULL);    //等待线程
    return 0;
}

编译一下

gcc cpu.c -pthread

thread 139946778752832 is running in processor 0

thread 139946770462464 is running in processor 1

可以看到我们将两个线程分别绑在了不同的CPU上面。

这里总结一下用到的基本函数:

cpp 复制代码
void CPU_ZERO (cpu_set_t *set);   //初始化,设为空

void CPU_SET (int cpu, cpu_set_t *set); //将某个cpu加入cpu集中 

void CPU_CLR (int cpu, cpu_set_t *set); //将某个cpu从cpu集中移出 

int CPU_ISSET (int cpu, const cpu_set_t *set); //判断某个cpu是否已在cpu集中设置了

int pthread_setaffinity_np(pthread_t thread,size_t cpusetsize,const cpu_set_t *cpuset); //设置CPU

int pthread_getaffinity_np(pthread_t thread,size_t cpusetsize, cpu_set_t *cpuset); //查看CPU
相关推荐
童槿顏丶8 分钟前
GitLab部署到Linux
linux·运维·gitlab
空堂与归3 小时前
Linux 命令实战:AI 开发者必备的终端操作手册
linux
牢姐与蒯4 小时前
Linux基本指令及知识点(二)
linux·运维·服务器
小玮看世界4 小时前
[Python]从“脏”数据到优雅实现:一个IoT滑动窗口最大值问题的测试驱动优化实录
linux·前端·python
RisunJan5 小时前
Linux命令-spell(Unix 拼写检查工具 —— 文本校对的基础利器)
linux·运维·unix
BLi4ee6 小时前
WSL 文件资源管理器左侧 Linux / Ubuntu 入口恢复
linux·ubuntu
BLUcoding7 小时前
Ubuntu 开机自启 Kiosk 模式浏览器全屏展示网页配置指南
linux·运维·ubuntu
Kina_C9 小时前
Keepalived 配置管理进阶:使用子配置文件实现模块化与高可读性
linux·网络·keepalived
wsad05329 小时前
CentOS Stream 10 配置静态 IP 完整指南
linux·tcp/ip·centos
Ai拆代码的曹操9 小时前
K8s 实战:CrashLoopBackOff 状态下 kubectl logs 拿不到日志的三层排查方案
linux·docker·kubernetes