
多线程并发学习笔记
C++并发多线程
纳兰小熊
Notes do not lie! 个人主页:https://liujf69.github.io/
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
C++并发多线程--简单线程池的实现
任务队列存储待执行的任务,线程数组存储多个线程,线程每次从任务队列中取任务来执行;原创 2023-08-22 00:37:55 · 255 阅读 · 0 评论 -
C++并发多线程--std::recursive_mutex和std::timed_mutex的使用
std::recursive_mutex 创建递归的独占互斥量,允许一个线程对其多次加锁和解锁;是直到某一时间内都在尝试获取锁,如果超过了规定的时间点仍无法获取锁,线程就会继续执行(跳过临界区的内容);等待一段时间来尝试获取锁,若无法获取锁,则线程继续执行(跳过临界区的内容);1--std::recursive_mutex的使用。1--std::recursive_mutex的使用。2--std::timed_mutex的使用。带有超时功能的独占互斥量,原创 2023-08-21 14:12:37 · 353 阅读 · 0 评论 -
C++并发多线程--std::async创建异步任务是否创建线程
使用 std::launch::deferred 或std::launch::async 时, 操作系统会。采取一种方式来执行异步任务(当系统资源充足时,会优先创建一个新线程,否则就会延迟执行异步任务),可以使用。当 std::async 创建一个异步任务。,其不一定会创建一个新线程去执行该任务;1--std::async创建异步任务。1--std::async创建异步任务。来判断异步任务处于哪种状态(来判断异步任务处于哪种状态(原创 2023-08-20 21:03:42 · 621 阅读 · 0 评论 -
C++并发多线程--std::future_status、std::shared_future和std::atomic的使用
std::future_status成员函数含有三种状态:timeout(执行超时)、ready(执行完毕)和deferred(延迟执行),其中 deferred 状态需要用 std::launch::deferred 对线程进行设置,使其延迟直到 get() 或者 wait() 被调用;由于 std::future 对象只能被 get() 一次(get()的实现基于移动语义),当多个线程都需要 std::future 对象 get() 的结果时,就会出错;3--std::atomic的使用。原创 2023-08-20 00:04:55 · 740 阅读 · 1 评论 -
C++并发多线程--std::async、std::packaged_task和std::promise的使用
std::launch::deferred 表示调用线程入口函数将会被延迟到 std::future 的 wait() 或 get() 调用,当 wait() 或者 get() 没有被调用时,线程入口函数不会被调用(线程不会被创建);std::promise 用于在其他线程中使用某个线程中的值;std::async用于启动一个异步任务,并返回一个std::future对象;std::packaged_task 用于打包任务,其包装各种可调用对象,方便后续作为线程入口函数;1--std::async的使用。原创 2023-08-18 21:09:26 · 692 阅读 · 0 评论 -
C++并发多线程--条件变量std::condition_variable的使用
notify_all() 可以同时唤醒多个线程,,当多个线程都会等待被唤醒时,所有线程都会被唤醒;(被唤醒的多个线程可能会竞争同一个互斥锁(假设线程共用一个锁))notify_one() 只能唤醒一个线程,当多个线程都等待被唤醒时,只会随机唤醒一个;2--notify_one()和notify_all()原创 2023-08-18 13:44:37 · 348 阅读 · 0 评论 -
C++并发多线程--单例设计模式和双重检查锁
这时候若其他线程发现了单例对象已被创建(已有地址空间),就可能会选择调用类对象的成员函数(但这时复杂的成员函数未初始化),就会出现错误;若一个类对象比较复杂和庞大,并且是可以复用的,当频繁地去创建和销毁类对象时就会造成巨大的性能浪费,通过单例设计模式将这个类对象设计为单例对象可以解决上述问题;双重检查锁可以避免多个线程发生数据竞争的情况,在下面的代码中使用双重检查锁可以避免多个线程同时创建类对象的情况(即执行 new MyCAS();3--std::call_once()的使用。(当需要实例时才去加载);原创 2023-08-16 19:04:37 · 886 阅读 · 0 评论 -
C++并发多线程--std::unique_lock的使用
与 std::lock_guard 中的 std::adopt_lock 类似,当 mutex 手动进行 lock() 后,std::unique_lock 可以使用 std::adopt_lock 告知不使用构造函数来自动 lock(),而只进行 unlock() 的操作;std::unique_lock 使用 std::defer_lock 时,不会对绑定的 mutex 进行 lock(),作用是将mutex 与线程进行。当使用 std::try_to_lock 参数时,发数据的线程会。原创 2023-08-16 17:38:19 · 563 阅读 · 1 评论 -
C++并发多线程--死锁问题及解决方法
这时就会出现死锁问题:线程 1 掌握 my_mutex1 的资源,需要使用 my_mutex2 的资源,而线程 2 掌握 my_mutex2 的资源,需要使用 my_mutex1 的资源;std::lock() 一般用于处理多个互斥量,其要么将多个互斥量同时锁住,要么将多个互斥量解锁(当部分互斥量未上锁时,要么等待其余互斥量上锁才继续执行,要么释放已经锁住的互斥量);std::lock() 可以锁住两个或两个以上的互斥量,可以避免因为互斥量上锁顺序不同而导致的死锁问题;来解决上面的死锁问题;原创 2023-08-14 19:47:50 · 872 阅读 · 0 评论 -
C++并发多线程--多个线程的数据共享和保护
不同线程对共享数据进行读写时,可能会发生冲突,因此需要进行特殊的处理(例如加锁,线程间需互斥等);多个线程的执行顺序与操作系统的调度机制有关,并不和创建线程的先后顺序相同;lock() 与 unlock() 必须成对匹配,即调用次数相同;当两个线程对共享数据进行读写时,会发生冲突,可以通过。一般会将多个线程对象存放在容器中,方便进行管理;创建多个线程时,可以使用同一个线程入口函数;进行上锁和解锁,即保护区域需正确;2-3--共享数据保护简单案例。1--创建并等待多个线程。原创 2023-08-14 19:03:40 · 1363 阅读 · 0 评论 -
C++并发多线程--临时对象的使用
当使用 detach 分离两个线程时,可能会出现主线程执行完毕了,主线程的变量 value 已被回收,而子线程来不及拷贝 value 变量来进行类的构造和析构操作;在上面的代码示例中,子线程需要使用主线程的变量 value 来进行构造和析构操作(具体可见构造和析构发生的线程 id 与主线程 id 不同);使用临时对象传递可以有效避免以上问题,因为临时对象的构造和析构发生在主线程中,可以有效避免由于生命周期导致的变量问题;由于变量生命周期的问题,可能会导致主线程执行完毕了,主线程的所有变量被回收;原创 2023-07-16 00:50:21 · 368 阅读 · 0 评论 -
C++并发多线程--创建线程
joinable() 用于判断是否可以使用 join() 或 detach(),能使用返回 true,不能使用返回 false(),当一个子线程调用 detach() 后不能再调用 join();使用 C++ 的 thread 标准库可以创建线程:常用的 API 有 join()、detach() 和 joinable() 等;detach() 用于分离子线程与主线程,主线程无需等待子线程执行完毕才结束,当主线程结束后,子线程转由后台运行;1--基于 thread 创建线程。原创 2023-07-14 21:25:36 · 491 阅读 · 1 评论