《使用C++实现线程编程》
在多核处理器普及的今天,线程编程已成为提升程序性能的关键技术。C++11标准引入的`
一、C++线程基础
C++11标准库中的`std::thread`类是线程编程的核心。创建线程的语法简洁直观:
#include
#include
void threadFunction() {
std::cout
上述代码展示了线程创建的基本流程:定义线程函数、创建`std::thread`对象、调用`join()`同步。若省略`join()`或`detach()`,程序会调用`std::terminate()`异常终止。
1.1 线程构造与析构
`std::thread`的构造函数支持多种参数形式:
- 无参函数:`std::thread t(func)`
- 带参函数:`std::thread t(func, arg1, arg2)`
- Lambda表达式:`std::thread t([](){ /* 代码 */ })`
- 成员函数:`std::thread t(&Class::method, objPtr)`
析构时必须显式处理线程状态:
std::thread t(func);
// 必须选择以下之一:
t.join(); // 等待线程结束
// 或
t.detach(); // 分离线程,资源由系统回收
1.2 线程标识与属性
通过`std::this_thread`命名空间可获取当前线程信息:
#include
#include
void printThreadInfo() {
std::cout
`hardware_concurrency()`返回系统支持的并发线程数,为线程池设计提供参考。
二、线程同步机制
多线程编程的核心挑战是数据竞争(Data Race)。C++11提供了多种同步原语解决此问题。
2.1 互斥锁(Mutex)
`std::mutex`是基础互斥机制,配合`std::lock_guard`实现RAII式管理:
#include
std::mutex mtx;
int sharedData = 0;
void increment() {
std::lock_guard<:mutex> lock(mtx); // 自动加锁/解锁
++sharedData;
}
对于需要多次加锁的场景,`std::unique_lock`更灵活:
std::unique_lock<:mutex> lock(mtx, std::defer_lock); // 延迟加锁
// ... 条件判断后
lock.lock();
2.2 条件变量(Condition Variable)
条件变量实现线程间通知机制,典型生产者-消费者模型:
#include
#include
std::queue dataQueue;
std::mutex mtx;
std::condition_variable cv;
void producer() {
for (int i = 0; i lock(mtx);
dataQueue.push(i);
cv.notify_one(); // 通知消费者
}
}
void consumer() {
while (true) {
std::unique_lock<:mutex> lock(mtx);
cv.wait(lock, [](){ return !dataQueue.empty(); }); // 等待条件满足
int val = dataQueue.front();
dataQueue.pop();
lock.unlock();
// 处理数据...
}
}
2.3 原子操作(Atomic)
对于简单变量,`std::atomic`提供无锁同步:
#include
std::atomic counter(0);
void increment() {
counter.fetch_add(1, std::memory_order_relaxed); // 原子递增
}
内存序参数(如`memory_order_seq_cst`)控制操作的全局顺序,需根据场景谨慎选择。
三、高级线程技术
3.1 异步任务(Future/Promise)
`std::future`和`std::promise`实现线程间值传递:
#include
int compute() {
return 42;
}
int main() {
std::promise prom;
std::future fut = prom.get_future();
std::thread t([&prom](){
prom.set_value(compute()); // 设置结果
});
std::cout
`std::async`进一步简化异步操作:
auto fut = std::async(std::launch::async, compute);
std::cout
3.2 线程池实现
线程池避免频繁创建销毁线程的开销。典型实现:
#include
#include
#include
class ThreadPool {
std::vector<:thread> workers;
std::queue<:function>> tasks;
std::mutex mtx;
std::condition_variable cv;
bool stop = false;
public:
ThreadPool(size_t threads) {
for (size_t i = 0; i task;
{
std::unique_lock<:mutex> lock(this->mtx);
this->cv.wait(lock, [this] {
return this->stop || !this->tasks.empty();
});
if (this->stop && this->tasks.empty()) return;
task = std::move(this->tasks.front());
this->tasks.pop();
}
task();
}
});
}
}
template
void enqueue(F&& f) {
{
std::unique_lock<:mutex> lock(mtx);
tasks.emplace([f]() { f(); });
}
cv.notify_one();
}
~ThreadPool() {
{
std::unique_lock<:mutex> lock(mtx);
stop = true;
}
cv.notify_all();
for (std::thread &worker : workers)
worker.join();
}
};
3.3 并行算法(C++17)
C++17在`
#include
#include
#include
int main() {
std::vector v = {3, 1, 4, 1, 5, 9};
std::sort(std::execution::par, v.begin(), v.end()); // 并行排序
return 0;
}
支持`par`(并行)、`seq`(顺序)、`par_unseq`(并行+向量化)三种执行策略。
四、最佳实践与调试技巧
4.1 避免常见陷阱
- 死锁:确保锁的获取顺序一致
- 锁粒度:过细导致性能下降,过粗引发竞争
- 虚假唤醒:条件变量必须使用谓词检查
4.2 性能优化
- 减少线程间共享数据
- 使用无锁数据结构(如`std::atomic`)
- 根据硬件并发数调整线程数量
4.3 调试工具
- GDB的`thread`命令查看线程状态
- Valgrind的Helgrind检测数据竞争
- TSan(ThreadSanitizer)编译器插件
五、完整示例:并行矩阵乘法
#include
#include
#include
#include
void multiplyRow(const std::vector<:vector>>& A,
const std::vector<:vector>>& B,
std::vector<:vector>>& C,
int row, std::mutex& mtx) {
for (int j = 0; j lock(mtx);
C[row][j] += A[row][k] * B[k][j];
}
}
}
void parallelMatrixMultiply(const std::vector<:vector>>& A,
const std::vector<:vector>>& B,
std::vector<:vector>>& C) {
std::mutex mtx;
std::vector<:thread> threads;
for (int i = 0; i > A = {{1,2,3},{4,5,6},{7,8,9}};
std::vector<:vector>> B = {{9,8,7},{6,5,4},{3,2,1}};
std::vector<:vector>> C(size, std::vector(size, 0));
parallelMatrixMultiply(A, B, C);
for (const auto& row : C) {
for (int val : row) {
std::cout
关键词
C++线程编程、std::thread、互斥锁、条件变量、原子操作、异步任务、线程池、并行算法、数据竞争、线程同步
简介
本文系统介绍C++11标准库中的线程编程技术,涵盖线程创建与管理、同步机制(互斥锁/条件变量/原子操作)、高级特性(异步任务/线程池/并行算法)及调试技巧,通过完整代码示例展示矩阵乘法的并行实现,帮助开发者掌握多线程编程的核心方法与实践。