线程

线程创建

C++11引入了强大的多线程支持,主要通过<thread>头文件提供。以下是详细介绍:

使用函数创建线程

使用Lambda表达式

使用类成员函数

线程管理

join() 和 detach()

检查线程状态

线程参数传递

按值传递

按引用传递

基础锁类型

互斥锁

std::mutex是最基本的互斥锁,同一时间只允许一个线程访问。

递归互斥锁

std::recursive_mutex允许同一线程多次获取同一个锁。

定时互斥锁

std::timed_mutex是支持超时的互斥锁。

递归定时互斥锁

std::recursive_timed_mutex是结合了递归和定时功能的互斥锁。

锁管理器

lock_guard

最简单的RAII锁管理器,构造时加锁,析构时自动解锁。

unique_lock

更灵活的锁管理器,支持延迟加锁、条件变量等。

shared_lock

用于读写锁的共享锁定。

避免死锁

同时锁定多个互斥锁,避免死锁。

try_lock系列

非阻塞的锁获取尝试。

锁的构造选项

defer_lock

延迟加锁,构造时不立即获取锁。

try_to_lock

尝试获取锁,不阻塞。

adopt_lock

接管已经获取的锁。

锁的性能对比

锁类型性能特性使用场景
mutex基础互斥一般同步
recursive_mutex递归锁定递归函数
timed_mutex超时机制需要超时控制
shared_mutex读写分离读多写少

条件变量

C++中使用条件变量可以使用std::condition_variable

Atomic类型

实现原理:

CAS机制:会将变量的预期值A与在内存中的值V进行比较,如果V与A是相等,就可以将该值改为B;如果V与A的值是不相等,那么就不能将其改为新值B。

生产者与消费者模型

类图

生产者消费者模型

代码

说明

TaskQueue(任务队列)

Producer(生产者)

Consumer(消费者)

面向对象的线程池

类图

面向对象的线程池

代码

说明

1. Task(抽象基类)


2. TaskQueue(任务队列)


3. ThreadPool(线程池)


4. Task1和Task2(具体任务实现)

基于对象的线程池

类图

基于对象的线程池

代码

说明

1. Task 类型别名


2. MyTask 类

功能:具体的任务实现类,演示如何创建可执行的任务。

核心方法


3. TaskQueue 类

功能:线程安全的任务队列,实现生产者-消费者模式。

私有成员

公有方法

构造函数

状态查询

任务操作

线程安全机制

  1. 互斥访问:使用 std::mutex 保护队列操作

  2. 条件等待

    • 队列满时,生产者线程等待 _notFull 条件

    • 队列空时,消费者线程等待 _notEmpty 条件

  3. 优雅退出:通过 _flag 标志位控制线程退出


4. ThreadPool 类

功能:线程池管理器,负责线程生命周期和任务分发。

私有成员

公有方法

构造函数

生命周期管理

任务管理

工作流程

1. 初始化阶段

  1. 创建 ThreadPool 实例,指定线程数和队列大小

  2. 调用 start() 方法启动指定数量的工作线程

  3. 每个工作线程执行 doTask() 方法,进入任务等待循环

2. 任务执行阶段

  1. 主线程通过 addTask() 添加任务到队列

  2. 工作线程从队列中获取任务并执行

  3. 使用条件变量实现高效的线程同步

3. 关闭阶段

  1. 等待队列中的所有任务执行完成

  2. 设置 _isAlive = false 停止接收新任务

  3. 调用 wakeAll() 唤醒所有等待的工作线程

  4. 等待所有工作线程结束(join()