C/C++ Linux/Unix 讓執行緒跑在指定 CPU 的方法 sched_setaffinity

本篇 ShengYu 介紹 C/C++ Linux/Unix 執行緒設定 CPU 的方法 sched_setaffinity()

主執行緒設定 CPU

主執行緒要設定跑在哪顆 CPU 的話,可以直接在 main 裡的主執行緒使用 sched_setaffinity() 設定即可,sched_setaffinity() 的第一個參數為 pid,
以我的電腦來說是單 CPU 4 核心,所以有 CPU0~CPU3 可以選擇,這邊示範選擇跑在 CPU3,

cpp-sched_setaffinity.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// g++ cpp-sched_setaffinity.cpp -o a.out
#include <stdio.h>
#include <sched.h> // for sched_setaffinity()
#include <unistd.h> // for getpid()

int main() {
int cpu_id = 3; // set thread to cpu3
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpu_id, &cpuset);

printf("sched_setaffinity cpu%d\n", cpu_id);
sched_setaffinity(getpid(), sizeof(cpuset), &cpuset);

printf("sched_getcpu = %d\n", sched_getcpu());

return 0;
}

也可以使用 pthread_setaffinity_np() 來設定 main 主執行緒跑在哪個 CPU。

在 pthread 執行緒設定 CPU

這邊示範用 pthread 建立出來的執行緒設定 CPU,
sched_setaffinity() 的第一個參數為 pid,如果傳入0的話就是會設定當前的執行緒,所以這邊在 foo() 函式裡使用 sched_setaffinity() 來設定,

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
// g++ cpp-sched_setaffinity-pthread.cpp -o a.out -pthread
#include <stdio.h>
#include <sched.h> // for sched_setaffinity()
#include <pthread.h>

void * foo(void *arg) {
int cpu_id = 3; // set thread to cpu3
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpu_id, &cpuset);

printf("sched_setaffinity cpu%d\n", cpu_id);
sched_setaffinity(0, sizeof(cpuset), &cpuset);

printf("t1 thread sched_getcpu = %d\n", sched_getcpu());
return NULL;
}

int main() {
pthread_t t1;
if (pthread_create(&t1, NULL, foo, NULL) != 0) {
fprintf(stderr, "Error: pthread_create\n");
}

//printf("sched_getcpu = %d\n", sched_getcpu());

pthread_join(t1, NULL);

return 0;
}

輸出結果如下,

1
2
sched_setaffinity cpu3
t1 thread sched_getcpu = 3

由於 sched_setaffinity() 的第一個參數是 pid,在指定 thread 要執行在哪顆 CPU 上的情況下不如 pthread_setaffinity_np() 來得方便,

在 C++ std::thread 執行緒設定 CPU

這邊示範用 C++ std::thread 建立出來的執行緒設定 CPU,基本上跟上例相似,

cpp-sched_setaffinity-std-thread.cpp
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
// g++ cpp-sched_setaffinity-std-thread.cpp -o a.out -std=c++11 -pthread
#include <iostream>
#include <thread>
#include <sched.h>
#include <pthread.h>
using namespace std;

void foo() {
int cpu_id = 3; // set thread to cpu3
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpu_id, &cpuset);

printf("sched_setaffinity cpu%d\n", cpu_id);
sched_setaffinity(0, sizeof(cpuset), &cpuset);

printf("t1 thread sched_getcpu = %d\n", sched_getcpu());
}

int main() {
thread t1(foo);

//printf("main thread sched_getcpu = %d\n", sched_getcpu());

if (t1.joinable()) {
t1.join();
}

return 0;
}

其它參考
sched_setaffinity(2) - Linux manual page
https://man7.org/linux/man-pages/man2/sched_setaffinity.2.html
multithreading - how to set CPU affinity of a particular pthread? - Stack Overflow
https://stackoverflow.com/questions/1407786/how-to-set-cpu-affinity-of-a-particular-pthread

其它相關文章推薦
C/C++ 新手入門教學懶人包
C/C++ Linux/Unix 讓執行緒跑在指定 CPU 的方法 pthread_setaffinity_np
C/C++ Linux/Unix pthread 建立多執行緒用法與範例
C++ std::thread 建立多執行緒用法與範例