C++多线程编程之青莲神决

球面无盲区多线程编程C++(天阶功法)

(助你金丹、元婴一念而至;洞虚、破妄唾手可得;化神、大乘扶摇直上…未完待续!)

一、多线程基础概念

1. 线程与进程
  • 进程:操作系统资源分配的基本单位,拥有独立内存空间
  • 线程:进程内的执行单元,共享进程内存,切换开销小
  • 并发 vs 并行
    • 并发:交替执行(单核)
    • 并行:同时执行(多核)
2. C++多线程支持
  • C++11开始原生支持多线程(<thread>头文件)
  • 替代方案:POSIX线程(pthread)、WinAPI线程

二、线程基本操作

1. 创建线程
#include <iostream>
#include <thread>

void task(int id) {
    std::cout << "Thread " << id << " running\n";
}

int main() {
    std::thread t1(task, 1);  // 创建线程并执行
    std::thread t2(task, 2);
    
    t1.join();  // 等待线程结束
    t2.join();
}
2. 线程参数传递
  • 值传递:默认方式(复制参数)
  • 引用传递:需使用std::ref
void modify(int& x) { x *= 2; }

int main() {
    int value = 5;
    std::thread t(modify, std::ref(value)); 
    t.join();
    std::cout << value;  // 输出10
}
3. 线程管理
  • join():阻塞等待线程结束
  • detach():分离线程(失去控制权,慎用!)
  • 线程IDstd::this_thread::get_id()

三、线程同步机制

1. 互斥锁(Mutex)
#include <mutex>

std::mutex mtx;
int shared_data = 0;

void increment() {
    for (int i = 0; i < 100000; ++i) {
        mtx.lock();
        ++shared_data;
        mtx.unlock();
    }
}

// 更安全的RAII方式
void safe_increment() {
    for (int i = 0; i < 100000; ++i) {
        std::lock_guard<std::mutex> lock(mtx);
        ++shared_data;
    }
}
2. 条件变量(Condition Variable)
#include <condition_variable>

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void producer() {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard<std::mutex> lock(mtx);
        ready = true;
    }
    cv.notify_one();
}

void consumer() {
    std::unique_lock<std::mutex> lock(mtx);
    cv.wait(lock, []{ return ready; });  // 自动释放锁并等待
    std::cout << "Data ready!\n";
}
3. 原子操作(Atomic)
#include <atomic>

std::atomic<int> counter(0);  // 无需锁的线程安全操作

void atomic_increment() {
    for (int i = 0; i < 100000; ++i) {
        ++counter;  // 原子操作
    }
}

四、高级同步工具

1. 读写锁(C++17)
#include <shared_mutex>

std::shared_mutex rw_mutex;
int data = 0;

// 写操作
void writer() {
    std::unique_lock lock(rw_mutex);  // 排他锁
    data = 42;
}

// 读操作
void reader() {
    std::shared_lock lock(rw_mutex);  // 共享锁
    std::cout << data;
}
2. 信号量(C++20)
#include <semaphore>

std::counting_semaphore<10> sem(3);  // 最大计数3

void worker() {
    sem.acquire();
    // 临界区操作
    sem.release();
}

五、异步编程模型

1. std::asyncstd::future
#include <future>

int compute(int x) { return x * x; }

int main() {
    std::future<int> fut = std::async(compute, 5);
    std::cout << "Result: " << fut.get();  // 阻塞获取结果
}
2. std::promisestd::future
void task(std::promise<int> prom) {
    prom.set_value(42);  // 设置结果
}

int main() {
    std::promise<int> prom;
    std::future<int> fut = prom.get_future();
    
    std::thread t(task, std::move(prom));
    t.detach();
    
    std::cout << "Result: " << fut.get();
}

六、线程安全设计原则

  1. RAII管理资源
    • 使用std::lock_guard/std::unique_lock自动管理锁
  2. 避免数据竞争
    • 共享数据必须通过同步机制访问
  3. 死锁预防
    • 按固定顺序获取锁
    • 使用std::scoped_lock(C++17)自动解决锁顺序
  4. 最小化锁粒度
    • 仅保护必要的数据
  5. 优先使用原子操作
    • 适用于简单状态的同步

七、C++20新特性

1. std::jthread(可联合线程)
std::jthread worker([](std::stop_token token) {
    while(!token.stop_requested()) {
        // 周期性任务
    }
});

worker.request_stop();  // 自动join
2. 停止令牌(Stop Token)
void worker(std::stop_token token) {
    while(!token.stop_requested()) {
        // 可中断的任务循环
    }
}

八、性能注意事项

  1. 避免虚假共享(False Sharing)
    • 将频繁访问的独立数据放置在不同缓存行
  2. 限制线程数量
    • 通常为CPU核心数的1-2倍
  3. 使用无锁数据结构
    • 适用于高并发场景
  4. 减少锁竞争
    • 使用细粒度锁或读写锁

九、调试与测试工具

  1. Thread Sanitizer(TSan)

    g++ -fsanitize=thread -g program.cpp
    
  2. Valgrind Helgrind

  3. 静态分析工具

    • Clang Thread Safety Analysis
    void foo() __attribute__((require_capability(mutex)));
    

十、综合示例:生产者-消费者模型

#include <queue>
#include <mutex>
#include <condition_variable>

template<typename T>
class SafeQueue {
public:
    void push(T value) {
        std::lock_guard lock(mtx);
        q.push(std::move(value));
        cv.notify_one();
    }

    T pop() {
        std::unique_lock lock(mtx);
        cv.wait(lock, [this]{ return !q.empty(); });
        T val = std::move(q.front());
        q.pop();
        return val;
    }

private:
    std::queue<T> q;
    std::mutex mtx;
    std::condition_variable cv;
};

void producer(SafeQueue<int>& q) {
    for(int i=0; i<10; ++i) q.push(i);
}

void consumer(SafeQueue<int>& q) {
    for(int i=0; i<10; ++i) {
        int val = q.pop();
        std::cout << "Got: " << val << "\n";
    }
}

int main() {
    SafeQueue<int> queue;
    std::jthread p(producer, std::ref(queue));
    std::jthread c(consumer, std::ref(queue));
}

总结

  1. 基础操作:掌握std::thread的创建、参数传递和生命周期管理
  2. 同步机制:理解互斥锁、条件变量、原子操作的使用场景
  3. 高级模式:熟练使用线程池、异步任务和现代线程管理工具
  4. 性能优化:注重减少锁竞争、避免虚假共享等关键问题
  5. 现代特性:关注C++20引入的jthread和停止令牌

通过合理运用这些技术,可以构建高效、安全的多线程程序,充分发挥现代多核处理器的性能潜力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值