C++ 中使用 std::thread 实现高效并行计算
在 C++ 中,std::thread
提供了一种简单而强大的方式来实现多线程并行计算。通过多线程,可以有效地提升计算密集型程序的性能,特别是在多核处理器上。下面是一个简单的示例,演示如何使用 std::thread
进行并行计算。
假设我们需要计算一个数组中每个元素的平方,然后将结果存储在另一个数组中。我们可以使用多个线程来并行处理这个任务。
#include <iostream>
#include <vector>
#include <thread>
// 一个函数,用于计算数组中一部分的平方
void computeSquares(const std::vector<int>& input, std::vector<int>& output, int start, int end) {
for (int i = start; i < end; ++i) {
output[i] = input[i] * input[i];
}
}
int main() {
const int dataSize = 1000000; // 1百万个元素
std::vector<int> input(dataSize);
std::vector<int> output(dataSize);
// 初始化输入数组
for (int i = 0; i < dataSize; ++i) {
input[i] = i;
}
const int numThreads = 4; // 使用4个线程
std::vector<std::thread> threads(numThreads);
int chunkSize = dataSize / numThreads;
// 创建并启动线程
for (int i = 0; i < numThreads; ++i) {
int start = i * chunkSize;
int end = (i == numThreads - 1) ? dataSize : start + chunkSize;
threads[i] = std::thread(computeSquares, std::ref(input), std::ref(output), start, end);
}
// 等待所有线程完成
for (auto& t : threads) {
t.join();
}
// 输出结果的一部分
std::cout << "First 10 squares: ";
for (int i = 0; i < 10; ++i) {
std::cout << output[i] << " ";
}
std::cout << std::endl;
return 0;
}
代码详解
初始化数据:首先,我们创建输入数组并用数据进行初始化。输出数组用于存储平方结果。
确定线程数:在这个例子中,我们使用了 4 个线程。
划分任务:将数据划分成大小相等的块,每个线程处理一个块。注意,最后一个线程可能会比其他线程多处理一些数据,以处理不可整除的情况。
创建线程:使用
std::thread
创建线程,并将划分的数据块传递给每个线程的工作函数computeSquares
。等待线程完成:调用
join
函数等待所有线程完成其任务。
注意事项
- 数据访问安全性:因为每个线程只访问特定的数组部分,所以不需要额外的同步机制(例如互斥锁)。
- 线程数量选择:选择合适的线程数量,通常建议与可用的处理器核心数量相匹配,但需根据具体应用场景进行调整。
- 捕获异常:在更复杂的程序中,捕获并处理线程可能抛出的异常也是重要的考虑。
通过这种方式,你可以在 C++ 中高效地利用多线程,实现并行计算,大大加速计算任务。