当前位置: 首页 > news >正文

C++多线程相关应用

一、多线程基础

1. 线程创建与管理

#include <thread>
#include <iostream>void task(int id) {std::cout << "Thread " << id << " executing\n";
}int main() {std::thread t1(task, 1);  // 创建线程std::thread t2([](){// Lambda表达式创建线程std::cout << "Lambda thread\n";});t1.join();  // 等待线程结束t2.join();// detach示例(谨慎使用)std::thread t3([]{/* 后台任务 */ });t3.detach();
}

2. 线程生命周期管理

  • join():阻塞等待线程结束
  • detach():分离线程(失去控制权)
  • RAII包装器:
    class ThreadGuard {std::thread& t;
    public:explicit ThreadGuard(std::thread& t_) : t(t_) {}~ThreadGuard() {if(t.joinable()) {t.join();  // 或根据需求选择detach}}
    };

二、互斥量(Mutex)应用

1. 基础锁机制

#include <mutex>std::mutex mtx;
int shared_data = 0;void safe_increment() {std::lock_guard<std::mutex> lock(mtx);  // RAII自动解锁++shared_data;
}// 递归锁示例
std::recursive_mutex rec_mtx;
void recursive_func(int n) {std::lock_guard<std::recursive_mutex> lock(rec_mtx);if(n > 0) recursive_func(n-1);
}

2. 死锁预防

// 使用std::lock同时锁定多个互斥量
std::mutex mtx1, mtx2;void safe_process() {std::unique_lock<std::mutex> lock1(mtx1, std::defer_lock);std::unique_lock<std::mutex> lock2(mtx2, std::defer_lock);std::lock(lock1, lock2);  // 原子化锁定// 临界区操作
}

三、条件变量(Condition Variable)

1. 生产者-消费者模型

#include <queue>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
std::queue<int> data_queue;void producer() {for(int i=0; i<5; ++i) {{std::lock_guard<std::mutex> lock(mtx);data_queue.push(i);}cv.notify_one();  // 通知消费者}
}void consumer() {while(true) {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, []{return !data_queue.empty(); }); // 防止虚假唤醒int data = data_queue.front();data_queue.pop();lock.unlock();std::cout << "Consumed: " << data << std::endl;if(data == 4) break;}
}

2. 条件变量使用要点

  • 始终在循环中检查条件
  • 使用notify_all()广播通知多个等待线程
  • 注意通知时机,避免丢失信号

四、原子变量(Atomic)

1. 基础使用

#include <atomic>std::atomic<int> counter(0);  // 无需锁的线程安全计数器void atomic_increment() {for(int i=0; i<1000; ++i) {counter.fetch_add(1, std::memory_order_relaxed);}
}// 测试代码
std::thread t1(atomic_increment);
std::thread t2(atomic_increment);
t1.join(); t2.join();
std::cout << "Final counter: " << counter << std::endl;  // 正确输出2000

2. 内存序选择

内存序 特性 使用场景
memory_order_relaxed 无顺序保证 计数器等简单操作
memory_order_consume 数据依赖排序 很少使用
memory_order_acquire 加载操作前的访问可见 锁获取
memory_order_release 存储操作后的修改可见 锁释放
memory_order_seq_cst 全局顺序一致(默认) 需要严格顺序的场景

五、综合应用案例

1. 线程池实现

#include <vector>
#include <future>class ThreadPool {std::vector<std::thread> workers;std::queue<std::function<void()>> tasks;std::mutex queue_mutex;std::condition_variable condition;bool stop = false;public:ThreadPool(size_t threads) {for(size_t i=0; i<threads; ++i) {workers.emplace_back([this] {while(true) {std::function<void()> task;{std::unique_lock<std::mutex> lock(queue_mutex);condition.wait(lock, [this]{return stop || !tasks.empty(); });if(stop && tasks.empty()) return;task = std::move(tasks.front());tasks.pop();}task();}});}}template<class F, class... Args>auto enqueue(F&& f, Args&&... args) -> std::future<decltype(f(args...))> {using return_type = decltype(f(args...));auto task = std::make_shared<std::packaged_task<return_type()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));std::future<return_type> res = task->get_future();{std::lock_guard<std::mutex> lock(queue_mutex);if(stop) throw std::runtime_error("enqueue on stopped ThreadPool");tasks.emplace([task](){(*task)(); });}condition.notify_one();return res;}~ThreadPool() {{std::lock_guard<std::mutex> lock(queue_mutex);stop = true;}condition.notify_all();for(std::thread &worker : workers)worker.join();}
};

六、性能优化与陷阱

1. 锁粒度控制

// 错误示例:大粒度锁
std::mutex big_lock;
void process_data() {std::lock_guard<std::mutex> lock(big_lock);  // 锁住整个函数// 长时间操作...
}// 优化:细粒度锁
struct DataPart {std::mutex mtx;int value;
};
DataPart part1, part2;void process_part(DataPart& part) {std::lock_guard<std::mutex> lock(part.mtx);// 操作单个数据部分
}

2. 虚假唤醒防护

std::condition_variable cv;
bool ready = false;  // 必须的条件判断变量// 正确写法
cv.wait(lock, []{return ready; }); // 错误写法(可能虚假唤醒)
while(!ready) cv.wait(lock);

3. 原子操作陷阱

std::atomic<bool> flag(false);
int non_atomic_data = 0;void thread1() {non_atomic_data = 42;          // ①flag.store(true);              // ②
}void thread2() {if(flag.load()) {// ③std::cout << non_atomic_data;  // ④ 可能看到0或42}
}
// 需要memory_order_release/acquire保证可见性

七、现代C++新特性

1. std::async异步操作

#include <future>auto future = std::async(std::launch::async, []{std::this_thread::sleep_for(1s);return 42;
});// 等待结果
std::cout << future.get() << std::endl;

2. 读写锁(C++17)

#include <shared_mutex>std::shared_mutex rw_mutex;
void reader() {std::shared_lock lock(rw_mutex);  // 共享锁// 读操作...
}void writer() {std::unique_lock lock(rw_mutex);  // 独占锁// 写操作...
}

八、调试与检测工具

  1. Thread Sanitizer(TSan)

    clang++ -fsanitize=thread -g program.cpp
  2. Mutex死锁检测

    // 使用std::scoped_lock(C++17)
    std::mutex mtx1, mtx2;
    std::scoped_lock lock(mtx1, mtx2);  // 自动死锁避免
  3. 性能分析工具

  • Perf
  • Intel VTune
  • Valgrind的DRD工具
http://www.jsqmd.com/news/28542/

相关文章:

  • CSP-J 2025 复赛解析
  • 加速 Docker 镜像下载的神器:KSpeeder 上手体验
  • Java桌面应用开发:JavaFX模块化与响应式
  • MyBatis 动态标签
  • 用 CSS Grid 实现高效布局的 3 个实战技巧
  • 【Linux 高效的系统】文件系统与软硬件连接
  • Webpack技术深度解析:模块打包与性能优化
  • Pinely Round 5 (Div. 1 + Div. 2) A+B+C+D
  • Spring Web MVC入门 - 指南
  • CSS:现代Web设计的不同技术
  • 左手坐标系和右手坐标系
  • ubuntu24 主题体验经验
  • 图神经网络(GNN)
  • docker部署OpenResume 开源简历生成器
  • 深入解析:MySQL 配置管理与日志系统完全指南:从基础到高级优化
  • 不使用 AAudio 的前提下,降低 Android 音频传输延时的方案
  • 深入解析:dmfldr快速装载工具使用
  • LINQ 表达式详解
  • 任务---网络通信组件JsonRpc
  • K230使用RTSP实现无线图传
  • 背单词 纯英文 2025年11月
  • 部署Docker开源记账神器Firefly III
  • 多车轨迹规划
  • 完整教程:RabbitMQ-如何保证消息不丢失
  • 2025 年 11 月酒店加盟公司最新推荐,聚焦高端定制需求与全案交付能力
  • 人工智能与信息物理系统(CPS)的会师:达成物理世界泛化应用的核心路径
  • 2025 年 11 月酒店加盟公司最新推荐,聚焦资质、案例、售后的五家酒店深度解读
  • 2025 年 11 月酒店加盟公司最新推荐,品牌实力与运营保障深度透视
  • Java学习之旅第一季-25:一维数组 - 教程
  • 类和对象-C++运算符重载project7