随着多核处理器的普及,并发编程成为提升程序性能的关键手段。C++ 自 C++11 标准引入线程支持后,提供了完整的多线程编程库,极大地方便了高性能并发程序的开发。
本篇文章将详细介绍 C++ 并发编程基础、线程管理、同步机制、原子操作、线程池设计及典型并发问题的解决方法,帮助读者掌握实用的并发开发技能。
C++11 引入 std::thread
,可方便创建线程。
cpp复制编辑#include <thread>
#include <iostream>
void worker(int id) {
std::cout << "线程 " << id << " 正在运行\n";
}
int main() {
std::thread t(worker, 1); // 创建线程
t.join(); // 等待线程结束
return 0;
}
join()
等待线程结束,阻塞调用线程。
detach()
让线程后台运行,主线程不等待。
线程对象销毁前必须调用 join()
或 detach()
,否则程序会异常终止。
并发环境中共享数据需要同步防止数据竞争。
cpp复制编辑#include <mutex>
std::mutex mtx;
int counter = 0;
void increment() {
std::lock_guard<std::mutex> lock(mtx);
++counter;
}
lock_guard
是 RAII 风格,确保锁的自动释放。
允许多个读线程并发,写线程独占。
cpp复制编辑#include <shared_mutex>
std::shared_mutex rw_mutex;
void read() {
std::shared_lock<std::shared_mutex> lock(rw_mutex);
// 读操作
}
void write() {
std::unique_lock<std::shared_mutex> lock(rw_mutex);
// 写操作
}
用于线程间等待和通知。
cpp复制编辑#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void wait_thread() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return ready; });
// 继续执行
}
void signal_thread() {
{
std::lock_guard<std::mutex> lock(mtx);
ready = true;
}
cv.notify_one();
}
支持原子读写,避免数据竞争。
cpp复制编辑#include <atomic>
std::atomic<int> count(0);
void increment() {
count.fetch_add(1, std::memory_order_relaxed);
}
定义操作的可见顺序,常用:
memory_order_relaxed
— 无同步,仅保证原子性。
memory_order_acquire
/ memory_order_release
— 用于同步。
memory_order_seq_cst
— 最强同步保证。
线程池复用线程资源,提高性能。
cpp复制编辑#include <vector>
#include <thread>
#include <queue>
#include <functional>
#include <condition_variable>
#include <atomic>
class ThreadPool {
std::vector<std::thread> workers;
std::queue<std::function<void()>> tasks;
std::mutex queue_mutex;
std::condition_variable condition;
std::atomic<bool> stop;
public:
ThreadPool(size_t threads) : stop(false) {
for (size_t i = 0; i < threads; ++i) {
workers.emplace_back([this] {
while (true) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(this->queue_mutex);
this->condition.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();
}
});
}
}
void enqueue(std::function<void()> task) {
{
std::lock_guard<std::mutex> lock(queue_mutex);
tasks.push(std::move(task));
}
condition.notify_one();
}
~ThreadPool() {
stop = true;
condition.notify_all();
for (auto &worker : workers) worker.join();
}
};
多个线程互相等待对方释放资源。
解决方案:
std::lock
同时锁多个 mutex
低优先级线程长时间得不到 CPU。
解决方案:
多个线程读写同一数据导致错误。
解决方案:
利用条件变量同步任务队列。
将大任务拆分并发执行,最后合并结果。
C++ 的并发编程提供了强大灵活的工具,但也带来复杂的同步问题。理解线程管理、同步机制和常见陷阱,是写出高效且安全并发程序的关键。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。