• CPU的亲缘性affinity


    前言

      本文简单介绍一下CPU亲缘性以及实现方法。

      本专栏知识点是通过零声教育的线上课学习,进行梳理总结写下文章,对c/c++linux课程感兴趣的读者,可以点击链接 C/C++后台高级服务器课程介绍 详细查看课程的服务。

    何谓亲缘性

      亲缘性的作用就是把线程or进程与CPU做黏合,也就是说,做了亲缘性的线程或进程,只会在这一个CPU核上运行,只在这一个CPU核上被调度,且不会切换到其他的CPU核上运行。这就是亲缘性。

    亲缘性API介绍

    • cpu_set_t mask:创建CPU核位图
    • CPU_ZERO(&mask):将位图置空
    • CPU_SET(self_id % num, &mask):将位图的某一位置1
    • sched_setaffinity(self_id, sizeof(mask), &mask):将对应进程或线程绑定到置1的这个CPU核上

    测试

    八个进程绑定八个CPU核心

    //
    // Created by 68725 on 2022/8/4.
    //
    #define _GNU_SOURCE             /* See feature_test_macros(7) */
    
    #include 
    #include 
    #include 
    
    
    void process_affinity(int num) {
        pid_t self_id = getpid();
    //    pid_t self_id = syscall(__NR_gettid);
    
        cpu_set_t mask;
    
        CPU_ZERO(&mask);
        //绑定某个CPU核心
        CPU_SET(self_id % num, &mask);
        //设置亲缘性
    //    sched_setaffinity(0, sizeof(mask), &mask);
        sched_setaffinity(self_id, sizeof(mask), &mask);
    
        while (1);
    }
    
    int main() {
        //获取cpu数量
        int cpu_num = sysconf(_SC_NPROCESSORS_CONF);
    
        int i;
        pid_t pid = 0;
        //创建与CPU数量一样多的进程
        for (i = 0; i < cpu_num; i++) {
            pid = fork();
            if (pid == (pid_t) 0) {
                break;
            }
        }
        if (pid == 0) {
            process_affinity(cpu_num);
        }
        while (1)usleep(1);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

      可以看到瞬间跑满了

    在这里插入图片描述

    在这里插入图片描述

    八个进程绑定四个CPU核心

    //
    // Created by 68725 on 2022/8/4.
    //
    #define _GNU_SOURCE             /* See feature_test_macros(7) */
    
    #include 
    #include 
    #include 
    
    
    void process_affinity(int num) {
        pid_t self_id = getpid();
    //    pid_t self_id = syscall(__NR_gettid);
    
        cpu_set_t mask;
    
        CPU_ZERO(&mask);
        //绑定某个CPU核心
        CPU_SET(self_id % num, &mask);
        //设置亲缘性
    //    sched_setaffinity(0, sizeof(mask), &mask);
        sched_setaffinity(self_id, sizeof(mask), &mask);
    
        while (1);
    }
    
    int main() {
        //获取cpu数量
        int cpu_num = sysconf(_SC_NPROCESSORS_CONF);
    
        int i;
        pid_t pid = 0;
        //创建与CPU数量一样多的进程
        for (i = 0; i < cpu_num; i++) {
            pid = fork();
            if (pid == (pid_t) 0) {
                break;
            }
        }
        if (pid == 0) {
            process_affinity(4);
        }
        while (1)usleep(1);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

      可以看到瞬间4个CPU核跑满

    在这里插入图片描述

    在这里插入图片描述

    八个进程绑定一个CPU核心

    //
    // Created by 68725 on 2022/8/4.
    //
    #define _GNU_SOURCE             /* See feature_test_macros(7) */
    
    #include 
    #include 
    #include 
    
    
    void process_affinity(int num) {
        pid_t self_id = getpid();
    //    pid_t self_id = syscall(__NR_gettid);
    
        cpu_set_t mask;
    
        CPU_ZERO(&mask);
        //绑定某个CPU核心
        CPU_SET(self_id % num, &mask);
        //设置亲缘性
    //    sched_setaffinity(0, sizeof(mask), &mask);
        sched_setaffinity(self_id, sizeof(mask), &mask);
    
        while (1);
    }
    
    int main() {
        //获取cpu数量
        int cpu_num = sysconf(_SC_NPROCESSORS_CONF);
    
        int i;
        pid_t pid = 0;
        //创建与CPU数量一样多的进程
        for (i = 0; i < cpu_num; i++) {
            pid = fork();
            if (pid == (pid_t) 0) {
                break;
            }
        }
        if (pid == 0) {
            process_affinity(1);
        }
        while (1)usleep(1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    【c语言基础题】— —第六版,可当作日常练习和期末复习,有奇效哟!
    SpringBoot SpringBoot 开发实用篇 2 配置高级 2.1 第三方bean 属性绑定
    【小笔记】MyBaits的Cursor
    快速排序算法(思路分析) [数据结构][Java]
    3. Python 变量和赋值
    Java | 选择排序算法实现
    java旋转base64位,自定义旋转角度角度
    QT笔记——QSlider滑动条滚轮事件和点击鼠标位置事件问题
    Mysql JSON
    聊聊KafkaListener的实现机制
  • 原文地址:https://blog.csdn.net/qq_42956653/article/details/126160543