1. Get the number of CPU cores
int CPU_NUM = sysconf(_SC_NPROCESSORS_CONF);
2. Threads are bound to CPU cores
① concept
CPU binding refers to binding a process or thread to a specified CPU core for execution in a multi-CPU system. In Linux, we can use the CPU affinity (affinity) attribute to bind a process to one or more CPU cores.
CPU Affinity is an attribute of a process, which indicates which CPUs the process scheduler can schedule the process to.
This property requires a process to run on a specified CPU for as long as possible without being migrated to another processor.
There are two types of CPU Affinity:
- soft affinity
- hard affinity
Soft affinity is just a suggestion. If it is unavoidable, the scheduler will still schedule the process to other CPUs for execution;
Hard affinity is a rule that the scheduler must abide by. The Linux kernel of version 2.6 or above allows developers to program to achieve hard affinity.
② function
The binding between process and CPU In Linux, a structure is used cpu_set_t
to represent the CPU Affinity mask, and a series of macros are defined to operate the set of schedulable CPUs of the process:
#define _GNU_SOURCE
#include <sched.h>
void CPU_ZERO(cpu_set_t *set); // 清除集合的内容,让其不包含任何 CPU。
void CPU_SET(int cpu, cpu_set_t *set); // 添加 CPU 到集合中
void CPU_CLR(int cpu, cpu_set_t *set); // 从集合中移除 CPU
int CPU_ISSET(int cpu, cpu_set_t *set); // 测试 CPU 是否在集合中
int CPU_COUNT(cpu_set_t *set); // 返回集合中包含的 CPU 数量
In Linux, the following two functions can be used to set and get the CPU Affinity property of a process:
#define _GNU_SOURCE
#include <sched.h>
/**
* 进程与 CPU 的绑定
*
* 该函数设置进程为 pid 的这个进程,让它运行在 mask 所设定的 CPU 上.
* 1. 如果 pid 的值为 0, 则表示指定的是当前进程, 使当前进程运行在mask所设定的那些 CPU 上
* 2. 第二个参数 cpusetsize 是 mask 所指定的数的长度. 通常设定为 sizeof(cpu_set_t).
* 如果当前 pid 所指定的进程此时没有运行在 mask 所指定的任意一个 CPU 上, 则该指定的
* 进程会从其它 CPU 上迁移到 mask 的指定的一个 CPU 上运行.
* 3. mask 为 CPU 核集合
*/
int sched_setaffinity(pid_t pid, size_t cpusetsize,const cpu_set_t *mask);
/**
* 该函数获得 pid 所指示的进程的 CPU 位掩码, 并将该掩码返回到 mask 所指向的结构中.
* 即获得指定 pid 当前可以运行在哪些 CPU 上. 同样,如果 pid 的值为 0. 也表示的是当前进程
*/
int sched_getaffinity(pid_t pid, size_t cpusetsize,cpu_set_t *mask);
/**
* 线程与 CPU 的绑定
*/
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);
In addition, the following function can be used to know which CPU the current process is running on:
int sched_getcpu(void);
If the call is successful, the function returns a non-negative CPU number value.
③ example
The following function binds different processes to different cores according to the different values entered when different processes are called, so as to utilize the multi-core of the CPU
void func(int i) {
cpu_set_t mask;
CPU_ZERO(&mask);
int cpu_num = sysconf(_SC_NPROCESSORS_CONF);
if (cpu_num == 0) {
cpu_num = 1;
}
CPU_SET((i % cpu_num), &mask);
sched_setaffinity(0, sizeof(cpu_set_t), &mask);
}
Kernel information through train: Linux kernel source code technology learning route + video tutorial code information
Learning through train: Linux kernel source code/memory tuning/file system/process management/device driver/network protocol stack
Original Author: Proficient in Linux Kernel
Original address: Linux Kernel: Process Management - CPU Affinity Setting - Zhihu (Copyright belongs to the author of the original text, please contact to delete the infringement message)