C++ 多线程【笔记】

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;
    }
};
相关推荐
carver w1 天前
MFC基于对话框Radio按钮的使用方法
c++·mfc
k***92161 天前
如何在C++的STL中巧妙运用std::find实现高效查找
java·数据结构·c++
Cappi卡比1 天前
性能提示(Performance Hints)
c++
王老师青少年编程1 天前
2025年12月GESP(C++四级): 建造
c++·算法·认证·gesp·csp·信奥赛·四级
闻缺陷则喜何志丹1 天前
【二分 寻找尾端】P7971 [KSN2021] Colouring Balls|普及+
c++·算法·二分·洛谷·寻找首端
qq_310658511 天前
webrtc源码走读(六)核心引擎层——安全模块
服务器·c++·音视频·webrtc
qq_310658511 天前
webrtc源码走读(七)核心引擎层——Qos模块
服务器·c++·音视频·webrtc
福楠1 天前
模拟实现string类
c语言·开发语言·c++·算法
..过云雨1 天前
计算机网络核心概述:网络通信协议及传输流程深度解析
linux·c++·网络协议·tcp/ip·计算机网络