目录1.Thread类默认构造函数 thread()带可调用对象的构造函数移动构造函数移动赋值操作符joinable()get_id()join()detach()swap()sleep_for()sleep_until()yield()get_id() (this_thread)std::thread::get_id() 与 std::this_thread::get_id() 的区别注意事项并发与并行的区别2.mutex类常用 mutex 类型lock()try_lock()unlock()std::lock_guardRAII包装器std::unique_lock灵活RAII包装器std::lock()辅助函数std::try_lock()辅助函数1.Thread类C11 标准库引入了std::thread类提供了跨平台的线程管理能力条件编译封装了各平台线程库接口使C语言原生支持多线程编程。std::thread 封装了操作系统线程的底层实现可以关联一个可调用对象函数指针、仿函数、lambda表达式、包装器作为线程入口点支持传递参数、获取线程ID、等待线程完成、分离线程等操作极大地简化了多线程程序的编写构造与赋值默认构造函数thread()项目说明接口名称thread() noexcept;功能描述创建一个不关联任何执行线程的线程对象处于空状态参数无返回值无使用示例std::thread t;注意事项该对象不表示任何线程调用join()或detach()会抛出异常需通过移动赋值关联实际线程带可调用对象的构造函数项目说明接口名称templateclass Callable, class... Args explicit thread(Callable f, Args... args);功能描述创建新线程并执行可调用对象f参数为args新线程立即开始执行参数f可调用对象函数、函数对象、lambdaargs传递给f的参数返回值无使用示例std::thread t(print, Hello, 100);std::thread t([](int x){ cout x; }, 42);注意事项参数默认以拷贝方式传递需要引用传递时使用std::ref()移动构造函数项目说明接口名称thread(thread other) noexcept;功能描述将other关联的线程所有权转移给新创建的对象other变为空状态参数other另一个thread右值引用对象返回值无使用示例std::thread t1(func);std::thread t2 std::move(t1);注意事项线程对象不可复制只能移动转移后原对象不可再用于join/detach移动赋值操作符项目说明接口名称thread operator(thread other) noexcept;功能描述将other关联的线程所有权转移给当前对象如果当前对象已关联线程则程序终止参数other另一个thread右值引用对象返回值当前对象的引用使用示例t1 std::move(t2);注意事项赋值前当前对象必须未关联线程已join或detach否则程序终止joinable()项目说明接口名称bool joinable() const noexcept;功能描述判断线程对象是否关联了一个活跃的可等待线程参数无返回值true关联活跃线程且未join/detachfalse无关联线程或已join/detach使用示例if (t.joinable()) { t.join(); }注意事项调用join()或detach()前应检查此状态避免异常get_id()项目说明接口名称std::thread::id get_id() const noexcept;功能描述返回与线程对象关联的线程ID若对象无关联线程则返回默认构造的id参数无返回值std::thread::id类型可比较、输出到流使用示例std::thread::id tid t.get_id();std::cout 线程ID: tid;注意事项线程ID可比较相等性用于识别不同线程join()项目说明接口名称void join();功能描述阻塞当前线程直到*this关联的线程执行完成参数无返回值无使用示例std::thread t(worker);t.join(); // 主线程等待worker完成注意事项同一线程不能多次join调用前应检查joinable()若线程已detach则抛出异常detach()项目说明接口名称void detach();功能描述将线程与thread对象分离线程独立在后台运行不再可等待参数无返回值无使用示例std::thread t(daemon_task);t.detach(); // 线程后台运行t不再关联注意事项分离后不能再join线程资源在线程结束时自动释放main结束可能影响分离线程swap()项目说明接口名称void swap(thread other) noexcept;功能描述交换两个thread对象关联的线程所有权参数other要交换的另一个thread对象返回值无使用示例std::thread t1(func1), t2(func2);t1.swap(t2); // 交换线程关联注意事项也可使用非成员函数std::swap(t1, t2)sleep_for()项目说明接口名称templateclass Rep, class Period void sleep_for(const std::chrono::durationRep, Period sleep_duration);功能描述阻塞当前线程至少指定的时间长度参数sleep_duration要休眠的时间长度返回值无使用示例std::this_thread::sleep_for(std::chrono::milliseconds(100));std::this_thread::sleep_for(std::chrono::seconds(2));注意事项可能因调度或资源竞争实际休眠时间更长sleep_until()项目说明接口名称templateclass Clock, class Duration void sleep_until(const std::chrono::time_pointClock, Duration sleep_time);功能描述阻塞当前线程直到指定的时间点参数sleep_time要唤醒的时间点返回值无使用示例auto wake_time std::chrono::system_clock::now() std::chrono::seconds(10);std::this_thread::sleep_until(wake_time);注意事项若时间点已过立即返回yield()项目说明接口名称void yield() noexcept;功能描述当前线程主动让出CPU时间片允许其他线程运行参数无返回值无使用示例while (!ready) { std::this_thread::yield(); }注意事项适合自旋等待场景减少CPU占用具体行为由调度器决定get_id() (this_thread)项目说明接口名称std::thread::id get_id() noexcept;功能描述获取当前调用线程的ID参数无返回值std::thread::id类型标识当前线程使用示例std::thread::id my_id std::this_thread::get_id();std::cout 当前线程: my_id;注意事项与thread对象的get_id()返回值类型相同可比较std::thread::get_id() 与 std::this_thread::get_id() 的区别比较维度std::thread::get_id()std::this_thread::get_id()所属对象std::thread类的成员函数std::this_thread命名空间的全局函数调用主体必须通过具体的thread对象调用任何地方均可直接调用返回谁的ID返回thread对象所关联线程的ID返回当前调用线程的ID调用时机可在任意线程调用获取的是对象关联的线程只能获取当前执行代码的线程返回值含义表示“那个线程”是谁表示“我自己”是谁空对象行为若thread对象未关联线程返回默认构造的id总是返回有效id总有当前线程std::thread::get_id 是“获取那个线程的ID”而 std::this_thread::get_id 是“获取我自己的ID”注意事项必须调用join或detach关联了线程的std::thread对象在析构前必须调用join()或detach()否则程序会终止防止“僵尸线程”现象确保线程资源被正确回收不可复制只可移动std::thread不可复制只能移动转移所有权防止同一资源多次释放参数传递线程函数的参数默认以拷贝方式传递需要使用std::ref传递引用异常安全注意在线程执行过程中抛出异常的处理并发与并行的区别维度并发并行核心定义逻辑上的同时处理看起来同时物理上的同时执行真正同时本质处理多个任务的能力同时执行多个任务的能力CPU核心单核或多核均可实现必须多核才能实现执行方式通过时间片轮转切换任务任务在不同核心上同时运行关注点任务调度、资源竞争加速计算、吞吐量类比一个人同时做几件事来回切换几个人同时做各自的事2.mutex类C11 标准库引入了std::mutex系列类提供了线程间互斥同步的原语用于保护共享数据免受多个线程同时访问导致的数据竞争。mutex 类封装了操作系统底层的互斥锁机制遵循 RAII 思想支持锁的获取、释放、尝试获取等操作是多线程编程中最基础的同步工具常用 mutex 类型类型头文件特性描述std::mutexmutex最基本的互斥锁提供独占所有权的非递归锁std::recursive_mutexmutex递归锁允许同一线程多次加锁需对应次数解锁std::timed_mutexmutex带超时功能的互斥锁支持尝试锁定时指定超时时间std::recursive_timed_mutexmutex递归锁 超时功能的组合lock()项目说明接口名称void lock();功能描述获取互斥锁的所有权如果锁已被其他线程持有则阻塞当前线程直到获取到锁参数无返回值无使用示例std::mutex mtx;void func() {mtx.lock();// 临界区代码mtx.unlock();}注意事项• 同一线程重复调用会导致死锁• 可能抛出异常如系统资源不足• 必须与unlock()成对使用try_lock()项目说明接口名称bool try_lock();功能描述尝试获取互斥锁若成功立即返回 true否则立即返回 false不会阻塞当前线程参数无返回值true成功获取锁false锁已被其他线程持有使用示例std::mutex mtx;void func() {if (mtx.try_lock()) {// 成功获取锁// 临界区代码mtx.unlock();} else {// 锁被占用做其他事情}}注意事项• 成功获取锁的线程必须调用unlock()• 适用于避免阻塞的场景如自旋等待unlock()项目说明接口名称void unlock();功能描述释放当前线程持有的互斥锁允许其他被阻塞的线程获取锁参数无返回值无使用示例std::mutex mtx;void func() {mtx.lock();// 临界区代码mtx.unlock(); // 释放锁}注意事项• 必须由持有锁的同一线程调用• 未持有锁时调用行为未定义• 忘记调用会导致死锁std::lock_guardRAII包装器项目说明类名std::lock_guardstd::mutex功能描述RAII资源获取即初始化包装器构造时自动调用lock()析构时自动调用unlock()构造函数参数mutex要管理的互斥锁使用示例std::mutex mtx;void func() {std::lock_guardstd::mutex lock(mtx);// 临界区代码自动加锁// 函数结束自动解锁}注意事项• 异常安全即使抛出异常也会自动解锁• 不可复制、不可移动构造加锁、析构解锁原则• 最简单、最推荐的用法• 无法手动控制解锁时机std::unique_lock灵活RAII包装器项目说明类名std::unique_lockstd::mutex功能描述灵活的RAII包装器支持延迟加锁、手动解锁、移动语义、尝试加锁等多种策略常用构造参数•mutex立即加锁•mutex, std::defer_lock延迟加锁不立即加锁•mutex, std::try_to_lock尝试加锁•mutex, std::adopt_lock接管已加锁的互斥量使用示例std::mutex mtx;void func() {std::unique_lockstd::mutex lock(mtx, std::defer_lock);// 做一些不需要锁的工作lock.lock(); // 需要时手动加锁// 临界区代码lock.unlock(); // 提前解锁// 做其他工作} // 析构时会检查是否仍持有锁若持有则自动解锁注意事项• 比lock_guard更灵活但有一定性能开销• 支持移动语义可返回函数• 可与条件变量配合使用• 可提前解锁普通互斥锁中间抛异常会导致死锁的根本原因是异常打断了正常的执行流程使unlock()无法被执行锁永远处于持有状态其他等待该锁的线程将永久阻塞std::lock()辅助函数项目说明接口名称templateclass Lockable1, class Lockable2, ... void std::lock(Lockable1 lock1, Lockable2 lock2, ...);功能描述同时锁定多个互斥锁使用死锁避免算法保证不会因锁定顺序导致死锁参数多个互斥锁对象的引用返回值无使用示例std::mutex mtx1, mtx2;void func() {std::unique_lockstd::mutex lock1(mtx1, std::defer_lock);std::unique_lockstd::mutex lock2(mtx2, std::defer_lock);std::lock(lock1, lock2); // 同时锁定两个互斥量// 操作两个共享资源} // 析构时自动解锁注意事项• 如果任一锁定操作抛出异常已成功的锁会自动释放• 通常与defer_lock配合使用• 可锁定任意数量互斥量std::try_lock()辅助函数项目说明接口名称templateclass Lockable1, class Lockable2, ... int std::try_lock(Lockable1 lock1, Lockable2 lock2, ...);功能描述依次尝试锁定多个互斥锁成功全部锁定返回 -1否则释放已锁定的锁并返回第一个失败的索引参数多个互斥锁对象的引用返回值-1全部锁定成功0~N-1第一个锁定失败的互斥锁索引使用示例std::mutex mtx1, mtx2;void func() {int result std::try_lock(mtx1, mtx2);if (result -1) {// 全部锁定成功// 操作共享资源mtx1.unlock();mtx2.unlock();} else {// 锁定失败result 指向失败的互斥锁}}注意事项• 按顺序尝试锁定• 任一失败时已成功的锁会自动释放• 返回值可用于诊断哪个锁失败