「C++ 多线程」硬件支持线程数、线程识别

文章大图来源: pixiv_id=104200866

1 CPU核心数和支持线程数

1.1 物理核心

物理核心 是 CPU 中实际存在的处理单元,每个物理核心可以独立地执行指令。例如,我的电脑的 CPU 是 24 核的,那么就有 24 个物理核心。

1.2 硬件支持线程数量(逻辑核心)

如果 不支持超线程技术,一个 24 核的 CPU,理想情况下可以支持 24 个线程并发(并行)执行。

如果 支持超线程技术,一个物理核心可以被模拟成两个逻辑核心来处理线程,从而使 CPU 能够同时处理更多的线程。例如一个 32 核的 CPU,如果支持超线程技术,理想情况下,可以支持 64 个线程并发(并行)执行。

1.3 std::thread::hardware_concurrency()

std::thread::hardware_concurrency() 是 std::thread 中的一个成员函数,用于确定系统硬件的并发度。该函数返回一个 std::size_t 类型的值,表示 硬件支持的并发线程数

std::thread::hardware_concurrency() 函数返回的值可能不是一个准确的值,只能作为一个线程支持数量的参考。在某些情况下,它可能返回 0,此时就无法确定硬件的并发度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <thread>

int main(){
size_t n = std::thread::hardware_concurrency();

if(n == 0){
std::cout << "The number of threads cannot be determined." << "\n";
}else{
std::cout << "The system supports approximately " << n << " threads." << "\n";
}

return 0;
}

在我的电脑上运行出来结果是 The system supports approximately 24 threads.,这与我电脑的 CPU 核心数量相同,也表明我的电脑是不支持超线程技术的。

2 线程识别

2.1

线程标识符(thread id)是一个对象,用于在程序中区分不同的线程。每个线程都有一个独一无二的标识符。

2.2 std::this_thread::get_id()

在 C++ 多线程编程中,std::this_thread::get_id() 可以获取当前线程的唯一标识符。

std::this_thread::get_id() 函数返回一个 std::thread::id 类型的值。std::thread::id 类型是一个类,用于表示线程的标识符。

不同的线程会返回不同的 std::thread::id 值。如果一个线程结束后,其 std::thread::id 可能会被系统重新分配给新创建的线程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <thread>
#include <vector>

void foo(){
std::cout << "thread id = " << std::this_thread::get_id() << "\n";
}

int main(){
std::vector<std::thread> pv(10);
for(auto& t : pv) t = std::thread(foo);
for(auto& t : pv){
if(t.joinable()){
t.join();
}
}

return 0;
}

运行结果如下:

所有线程并发执行,且线程 id 各不相同。

参考

  1. C++ 并发编程实战 第 2 章 线程管理

「C++ 多线程」硬件支持线程数、线程识别
https://marisamagic.github.io/2024/12/23/20241223/
作者
MarisaMagic
发布于
2024年12月23日
许可协议