C++多线程编程深度解析
1. 同步多线程编程
基础同步原语
互斥锁(Mutex)
cpp
复制代码
#include <mutex>
#include <thread>
#include <vector>
class ThreadSafeCounter {
private:
mutable std::mutex mutex_;
int value_ = 0;
public:
void increment() {
std::lock_guard<std::mutex> lock(mutex_);
++value_;
}
int get() const {
std::lock_guard<std::mutex> lock(mutex_);
return value_;
}
// 使用unique_lock实现条件等待
void wait_until(int target) {
std::unique_lock<std::mutex> lock(mutex_);
// 条件变量配合unique_lock使用
}
};
// 递归互斥锁
class RecursiveExample {
private:
std::recursive_mutex mutex_;
int value_ = 0;
void internal_update(int delta) {
std::lock_guard<std::recursive_mutex> lock(mutex_);
value_ += delta;
}
public:
void complex_operation() {
std::lock_guard<std::recursive_mutex> lock(mutex_);
internal_update(10); // 递归调用,不会死锁
internal_update(-5);
}
};
条件变量(Condition Variable)
cpp
复制代码
#include <condition_variable>
class BoundedBuffer {
private:
std::vector<int> buffer_;
size_t capacity_;
size_t front_ = 0;
size_t rear_ = 0;
size_t count_ = 0;
std::mutex mutex_;
std::condition_variable not_full_;
std::condition_variable not_empty_;
public:
explicit BoundedBuffer(size_t capacity) : capacity_(capacity) {
buffer_.resize(capacity);
}
void produce(int value) {
std::unique_lock<std::mutex> lock(mutex_);
// 等待缓冲区不满
not_full_.wait(lock, { return count_ < capacity_; });
buffer_[rear_] = value;
rear_ = (rear_ + 1) % capacity_;
++count_;
lock.unlock();
not_empty_.notify_one(); // 通知消费者
}
int consume() {
std::unique_lock<std::mutex> lock(mutex_);
// 等待缓冲区不空
not_empty_.wait(lock, { return count_ > 0; });
int value = buffer_[front_];
front_ = (front_ + 1) % capacity_;
--count_;
lock.unlock();
not_full_.notify_one(); // 通知生产者
return value;
}
};
高级同步模式
读写锁(Read-Write Lock)
cpp
复制代码
#include <shared_mutex>
class ThreadSafeHashMap {
private:
std::unordered_map<std::string, int> data_;
mutable std::shared_mutex rw_mutex_; // C++17
public:
// 读操作使用共享锁
int get(const std::string& key) const {
std::shared_lock<std::shared_mutex> lock(rw_mutex_);
auto it = data_.find(key);
return it != data_.end() ? it->second : -1;
}
// 写操作使用独占锁
void set(const std::string& key, int value) {
std::unique_lock<std::shared_mutex> lock(rw_mutex_);
data_[key] = value;
}
// 批量读操作
std::vector<std::string> keys() const {
std::shared_lock<std::shared_mutex> lock(rw_mutex_);
std::vector<std::string> result;
for (const auto& pair : data_) {
result.push_back(pair.first);
}
return result;
}
};
屏障(Barrier) - C++20
cpp
复制代码
#include <barrier>
class ParallelAlgorithm {
private:
std::vector<int> data_;
std::barrier<> sync_point_;
int thread_count_;
public:
ParallelAlgorithm(const std::vector<int>& input, int threads)
: data_(input), thread_count_(threads),
sync_point_(threads, { phase_completion(); }) {}
void parallel_process() {
std::vector<std::jthread> workers;
for (int i = 0; i < thread_count_; ++i) {
workers.emplace_back( {
// 第一阶段处理
process_phase1(i);
sync_point_.arrive_and_wait(); // 等待所有线程完成第一阶段
// 第二阶段处理
process_phase2(i);
sync_point_.arrive_and_wait(); // 等待所有线程完成第二阶段
});
}
}
private:
void process_phase1(int thread_id) {
// 第一阶段处理逻辑
size_t chunk_size = data_.size() / thread_count_;
size_t start = thread_id * chunk_size;
size_t end = (thread_id == thread_count_ - 1) ? data_.size() : start + chunk_size;
for (size_t i = start; i < end; ++i) {
data_[i] *= 2;
}
}
void process_phase2(int thread_id) {
// 第二阶段处理逻辑
}
void phase_completion() {
// 所有线程完成一个阶段后执行
std::cout << "Phase completed\n";
}
};
2. 异步多线程编程
Future/Promise模式
基础异步操作
cpp
复制代码
#include <future>
#include <chrono>
class AsyncProcessor {
public:
// 异步执行函数
std::future<int> async_compute(int input) {
return std::async(std::launch::async, {
std::this_thread::sleep_for(std::chrono::seconds(1));
return input * input;
});
}
// 使用promise主动设置结果
std::future<std::string> async_download(const std::string& url) {
auto promise = std::make_shared<std::promise<std::string>>();
std::thread( {
try {
// 模拟下载操作
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::string result = "Downloaded: " + url;
promise->set_value(result);
} catch (...) {
promise->set_exception(std::current_exception());
}
}).detach();
return promise->get_future();
}
// 批量异步操作
std::vector<std::future<int>> parallel_transform(
const std::vector<int>& input) {
std::vector<std::future<int>> results;
results.reserve(input.size());
for (int value : input) {
results.push_back(std::async(std::launch::async, {
// 模拟耗时计算
std::this_thread::sleep_for(std::chrono::milliseconds(100));
return value * value;
}));
}
return results;
}
};
// 使用示例
void use_async_processor() {
AsyncProcessor processor;
// 单个异步操作
auto future1 = processor.async_compute(42);
auto future2 = processor.async_download("http://example.com");
// 等待结果
int result1 = future1.get();
std::string result2 = future2.get();
std::cout << "Result1: " << result1 << ", Result2: " << result2 << std::endl;
// 批量操作
std::vector<int> inputs{1, 2, 3, 4, 5};
auto futures = processor.parallel_transform(inputs);
for (auto& future : futures) {
std::cout << future.get() << " ";
}
std::cout << std::endl;
}
高级异步模式
异步管道(Async Pipeline)
cpp
复制代码
#include <queue>
template<typename T>
class AsyncPipeline {
private:
std::queue<std::future<T>> stages_;
std::mutex queue_mutex_;
std::condition_variable queue_cv_;
bool stopped_ = false;
public:
template<typename Func>
void add_stage(Func&& func) {
std::lock_guard<std::mutex> lock(queue_mutex_);
if (stopped_) throw std::runtime_error("Pipeline stopped");
stages_.push(std::async(std::launch::async, std::forward<Func>(func)));
queue_cv_.notify_one();
}
std::future<T> get_result() {
std::unique_lock<std::mutex> lock(queue_mutex_);
queue_cv_.wait(lock, {
return !stages_.empty() || stopped_;
});
if (stages_.empty()) {
throw std::runtime_error("No results available");
}
auto future = std::move(stages_.front());
stages_.pop();
return future;
}
void stop() {
std::lock_guard<std::mutex> lock(queue_mutex_);
stopped_ = true;
queue_cv_.notify_all();
}
};
// 使用示例:图像处理管道
void image_processing_pipeline() {
AsyncPipeline<std::vector<int>> pipeline;
// 第一阶段:加载图像
pipeline.add_stage( -> std::vector<int> {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
return {1, 2, 3, 4, 5}; // 模拟图像数据
});
// 第二阶段:处理图像
pipeline.add_stage( -> std::vector<int> {
auto data = std::vector<int>{1, 2, 3, 4, 5}; // 实际应从上一阶段获取
for (auto& pixel : data) pixel *= 2;
return data;
});
// 获取最终结果
auto result = pipeline.get_result().get();
for (int pixel : result) {
std::cout << pixel << " ";
}
std::cout << std::endl;
}
异步任务调度器
cpp
复制代码
#include <functional>
#include <priority_queue>
class AsyncTaskScheduler {
private:
struct Task {
std::function<void()> function;
std::chrono::steady_clock::time_point execute_time;
int priority;
bool operator<(const Task& other) const {
if (execute_time != other.execute_time) {
return execute_time > other.execute_time; // 小顶堆
}
return priority < other.priority;
}
};
std::priority_queue<Task> task_queue_;
std::mutex queue_mutex_;
std::condition_variable queue_cv_;
std::jthread worker_thread_;
bool stopped_ = false;
public:
AsyncTaskScheduler() : worker_thread_( { run_scheduler(); }) {}
~AsyncTaskScheduler() {
{
std::lock_guard<std::mutex> lock(queue_mutex_);
stopped_ = true;
}
queue_cv_.notify_all();
}
template<typename Func>
void schedule(Func&& func, int priority = 0) {
schedule_at(std::forward<Func>(func),
std::chrono::steady_clock::now(), priority);
}
template<typename Func, typename Rep, typename Period>
void schedule_after(Func&& func,
const std::chrono::duration<Rep, Period>& delay,
int priority = 0) {
schedule_at(std::forward<Func>(func),
std::chrono::steady_clock::now() + delay, priority);
}
template<typename Func>
void schedule_at(Func&& func,
std::chrono::steady_clock::time_point time,
int priority = 0) {
std::lock_guard<std::mutex> lock(queue_mutex_);
task_queue_.push(Task{
std::forward<Func>(func),
time,
priority
});
queue_cv_.notify_one();
}
private:
void run_scheduler() {
while (true) {
std::unique_lock<std::mutex> lock(queue_mutex_);
if (stopped_) break;
if (task_queue_.empty()) {
queue_cv_.wait(lock);
continue;
}
const auto& next_task = task_queue_.top();
auto now = std::chrono::steady_clock::now();
if (next_task.execute_time <= now) {
// 执行任务
Task task = next_task;
task_queue_.pop();
lock.unlock();
try {
task.function();
} catch (const std::exception& e) {
std::cerr << "Task failed: " << e.what() << std::endl;
}
} else {
// 等待到任务执行时间
queue_cv_.wait_until(lock, next_task.execute_time);
}
}
}
};
3. 原子操作与无锁编程
原子类型与内存顺序
cpp
复制代码
#include <atomic>
class LockFreeCounter {
private:
std::atomic<int> count_{0};
std::atomic<bool> flag_{false};
public:
void increment() {
// 宽松内存顺序:只保证原子性
count_.fetch_add(1, std::memory_order_relaxed);
}
int get() const {
// 获取操作需要acquire语义
return count_.load(std::memory_order_acquire);
}
// 使用CAS(Compare-And-Swap)实现无锁操作
bool try_update(int expected, int new_value) {
return count_.compare_exchange_weak(
expected, new_value,
std::memory_order_acq_rel,
std::memory_order_acquire
);
}
// 自旋锁使用原子标志
void lock() {
while (flag_.exchange(true, std::memory_order_acquire)) {
// 自旋等待
while (flag_.load(std::memory_order_relaxed)) {
std::this_thread::yield();
}
}
}
void unlock() {
flag_.store(false, std::memory_order_release);
}
};
// 无锁栈实现
template<typename T>
class LockFreeStack {
private:
struct Node {
T data;
Node* next;
Node(const T& data) : data(data), next(nullptr) {}
};
std::atomic<Node*> head_{nullptr};
public:
void push(const T& data) {
Node* new_node = new Node(data);
new_node->next = head_.load(std::memory_order_relaxed);
while (!head_.compare_exchange_weak(
new_node->next, new_node,
std::memory_order_release,
std::memory_order_relaxed)) {
// CAS失败,重试
}
}
std::optional<T> pop() {
Node* old_head = head_.load(std::memory_order_acquire);
while (old_head &&
!head_.compare_exchange_weak(
old_head, old_head->next,
std::memory_order_acq_rel,
std::memory_order_acquire)) {
// CAS失败,重试
}
if (!old_head) return std::nullopt;
T data = std::move(old_head->data);
delete old_head;
return data;
}
};
4. 线程池与执行器模式
高级线程池实现
cpp
复制代码
#include <deque>
class ThreadPool {
private:
std::vector<std::jthread> workers_;
std::deque<std::function<void()>> tasks_;
std::mutex queue_mutex_;
std::condition_variable queue_cv_;
std::condition_variable completion_cv_;
bool stopped_ = false;
std::atomic<int> active_tasks_{0};
public:
explicit ThreadPool(size_t threads = std::thread::hardware_concurrency()) {
workers_.reserve(threads);
for (size_t i = 0; i < threads; ++i) {
workers_.emplace_back( { worker_loop(); });
}
}
~ThreadPool() {
{
std::unique_lock<std::mutex> lock(queue_mutex_);
stopped_ = true;
}
queue_cv_.notify_all();
}
template<typename Func>
auto submit(Func&& func) -> std::future<decltype(func())> {
using return_type = decltype(func());
auto task = std::make_shared<std::packaged_task<return_type()>>(
std::forward<Func>(func)
);
std::future<return_type> result = task->get_future();
{
std::unique_lock<std::mutex> lock(queue_mutex_);
if (stopped_) throw std::runtime_error("ThreadPool stopped");
tasks_.emplace_back( { (*task)(); });
++active_tasks_;
}
queue_cv_.notify_one();
return result;
}
void wait_completion() {
std::unique_lock<std::mutex> lock(queue_mutex_);
completion_cv_.wait(lock, {
return tasks_.empty() && active_tasks_ == 0;
});
}
private:
void worker_loop() {
while (true) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(queue_mutex_);
queue_cv_.wait(lock, {
return stopped_ || !tasks_.empty();
});
if (stopped_ && tasks_.empty()) return;
task = std::move(tasks_.front());
tasks_.pop_front();
}
task(); // 执行任务
{
std::lock_guard<std::mutex> lock(queue_mutex_);
--active_tasks_;
if (active_tasks_ == 0 && tasks_.empty()) {
completion_cv_.notify_all();
}
}
}
}
};
// 使用示例
void use_thread_pool() {
ThreadPool pool(4);
std::vector<std::future<int>> results;
// 提交多个任务
for (int i = 0; i < 10; ++i) {
results.push_back(pool.submit( {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
return i * i;
}));
}
// 等待所有任务完成
pool.wait_completion();
// 获取结果
for (auto& result : results) {
std::cout << result.get() << " ";
}
std::cout << std::endl;
}
5. 性能优化与最佳实践
避免虚假共享(False Sharing)
cpp
复制代码
#include <new>
// 缓存行对齐的结构
struct alignas(64) CacheAlignedCounter { // 64字节对齐
std::atomic<int> value{0};
char padding[64 - sizeof(std::atomic<int>)];
};
class FalseSharingDemo {
private:
// 错误的布局:可能在同一缓存行
std::atomic<int> counter1_{0};
std::atomic<int> counter2_{0};
// 正确的布局:强制不同缓存行
CacheAlignedCounter aligned_counter1_;
CacheAlignedCounter aligned_counter2_;
public:
void increment_bad() { // 可能产生虚假共享
counter1_.fetch_add(1, std::memory_order_relaxed);
counter2_.fetch_add(1, std::memory_order_relaxed);
}
void increment_good() { // 避免虚假共享
aligned_counter1_.value.fetch_add(1, std::memory_order_relaxed);
aligned_counter2_.value.fetch_add(1, std::memory_order_relaxed);
}
};
线程局部存储
cpp
复制代码
#include <thread>
class PerThreadData {
private:
// 线程局部存储
static thread_local int thread_id_;
static thread_local std::string thread_name_;
public:
static void initialize_thread(int id, const std::string& name) {
thread_id_ = id;
thread_name_ = name;
}
static void process_data() {
// 每个线程有自己的数据副本
std::cout << "Thread " << thread_id_ << " (" << thread_name_
<< ") processing data\n";
}
};
// 定义线程局部变量
thread_local int PerThreadData::thread_id_ = 0;
thread_local std::string PerThreadData::thread_name_ = "unknown";
void use_thread_local() {
std::vector<std::jthread> threads;
for (int i = 0; i < 3; ++i) {
threads.emplace_back( {
PerThreadData::initialize_thread(i, "worker_" + std::to_string(i));
PerThreadData::process_data();
});
}
}
6. 现代C++多线程特性
C++20 信号量(Semaphore)
cpp
复制代码
#include <semaphore>
class SemaphoreExample {
private:
std::counting_semaphore<5> semaphore_{5}; // 允许5个并发访问
public:
void limited_access(int thread_id) {
semaphore_.acquire(); // 获取信号量
// 临界区
std::cout << "Thread " << thread_id << " entered critical section\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "Thread " << thread_id << " leaving critical section\n";
semaphore_.release(); // 释放信号量
}
};
C++20 闩锁(Latch)与屏障
cpp
复制代码
#include <latch>
#include <barrier>
class LatchBarrierExample {
public:
void parallel_initialization() {
constexpr int thread_count = 4;
std::latch completion_latch(thread_count);
std::barrier sync_barrier(thread_count);
std::vector<std::jthread> workers;
for (int i = 0; i < thread_count; ++i) {
workers.emplace_back( {
// 初始化阶段
initialize_phase(i);
completion_latch.count_down(); // 通知初始化完成
// 等待所有线程初始化完成
completion_latch.wait();
// 同步处理阶段
sync_barrier.arrive_and_wait();
process_phase(i);
sync_barrier.arrive_and_wait();
finalize_phase(i);
});
}
}
private:
void initialize_phase(int thread_id) {
std::cout << "Thread " << thread_id << " initializing\n";
}
void process_phase(int thread_id) {
std::cout << "Thread " << thread_id << " processing\n";
}
void finalize_phase(int thread_id) {
std::cout << "Thread " << thread_id << " finalizing\n";
}
};
7. 最佳实践总结
同步多线程使用场景
cpp
复制代码
// ✅ 适合同步的场景:
// 1. 需要严格控制执行顺序
// 2. 共享资源需要互斥访问
// 3. 线程间需要明确的数据依赖
// 4. 需要等待特定条件满足
// 示例:生产者-消费者模式
class ProducerConsumer {
std::queue<Data> buffer_;
std::mutex mutex_;
std::condition_variable not_empty_;
std::condition_variable not_full_;
public:
void produce(Data data) {
std::unique_lock<std::mutex> lock(mutex_);
not_full_.wait(lock, { return buffer_.size() < max_size; });
buffer_.push(std::move(data));
not_empty_.notify_one();
}
Data consume() {
std::unique_lock<std::mutex> lock(mutex_);
not_empty_.wait(lock, { return !buffer_.empty(); });
Data data = std::move(buffer_.front());
buffer_.pop();
not_full_.notify_one();
return data;
}
};
异步多线程使用场景
cpp
复制代码
// ✅ 适合异步的场景:
// 1. 独立计算任务
// 2. I/O密集型操作
// 3. 需要后台处理的任务
// 4. 任务间依赖关系复杂
// 示例:异步Web服务器
class AsyncWebServer {
ThreadPool pool_;
std::unordered_map<int, std::future<Response>> pending_requests_;
public:
void handle_request(int request_id, const Request& req) {
auto future = pool_.submit( {
// 模拟处理请求
std::this_thread::sleep_for(std::chrono::milliseconds(100));
return process_request(req);
});
pending_requests_[request_id] = std::move(future);
}
std::optional<Response> get_response(int request_id) {
auto it = pending_requests_.find(request_id);
if (it == pending_requests_.end()) return std::nullopt;
if (it->second.wait_for(std::chrono::seconds(0)) ==
std::future_status::ready) {
Response response = it->second.get();
pending_requests_.erase(it);
return response;
}
return std::nullopt;
}
};
性能优化建议
cpp
复制代码
// 1. 选择合适的锁粒度
class OptimizedCounter {
private:
// 细粒度锁:每个计数器独立
struct Counter {
std::atomic<int> value{0};
std::mutex mutex;
};
std::vector<Counter> counters_;
public:
void increment(int index) {
std::lock_guard<std::mutex> lock(counters_[index].mutex);
++counters_[index].value;
}
};
// 2. 避免锁的嵌套
class LockHierarchy {
private:
std::mutex mutex1_, mutex2_;
public:
// 错误的嵌套顺序
void bad_method() {
std::lock_guard<std::mutex> lock1(mutex1_);
std::lock_guard<std::mutex> lock2(mutex2_); // 可能死锁
}
// 正确的固定顺序
void good_method() {
std::lock_guard<std::mutex> lock1(mutex1_);
std::lock_guard<std::mutex> lock2(mutex2_); // 总是先锁mutex1
}
};
// 3. 使用无锁数据结构
template<typename T>
class LockFreeQueue {
// 实现无锁队列
public:
void push(const T& value) {
// 无锁实现
}
std::optional<T> pop() {
// 无锁实现
return std::nullopt;
}
};