C++11并发与多线程

1. 基本概念

1.1 并发

  • 多个任务同时进行(假象)
  • 目的:是提高效率
  • 策略:是时间片轮询,上下文切换
  • 单核
  • 多核(硬件并发)
  • 多进程并发,进程启动速度慢,资源占用高,进程间通信
  • 多线程并发,线程启动速度快,资源占用低,共享内存地址空间,访问互斥

1.2 可执行程序

1.3 进程

1.4 线程

  • 多线程优点:可以同时并发处理多个任务。
  • 每个进程都有唯一的一个主线程,主线程的生命周期与进程一致,主线程执行完毕代表进程执行完毕。
  • 除了主线程外,可以通过代码来创建其他工作线程。
  • 线程是用来执行代码的,每个线程都有一条代码执行路径。
  • 线程不是越多越好,每个线程需要栈空间,需要上下文切换,保存上下文状态。
  • 多线程优化

2. 概述

C++ 中关于并发多线程的部分,主要包含 <thread>、<mutex>、<atomic>、<condition_varible>、<future>五个部分。

  • <atomic>:该头文主要声明了两个类, std::atomic 和 std::atomic_flag,另外还声明了一套 C 风格的原子类型和与 C 兼容的原子操作的函数。
  • <thread>:该头文件主要声明了 std::thread 类,另外 std::this_thread 命名空间也在该头文件中。
  • <mutex>:该头文件主要声明了与互斥量(mutex)相关的类,包括 std::mutex 系列类,std::lock_guard, std::unique_lock, 以及其他的类型和函数。
  • <condition_variable>:该头文件主要声明了与条件变量相关的类,包括 std::condition_variable 和 std::condition_variable_any。
  • <future>:该头文件主要声明了 std::promise, std::package_task 两个 Provider 类,以及 std::future 和 std::shared_future 两个 Future 类,另外还有一些与之相关的类型和函数,std::async() 函数就声明在此头文件中。

3. 创建多线程

  • C++ 98标准,需要自己实现跨平台的封装库或者引用第三方库。
  • C++ 11 多线程新标准,C++ 语言本身增加对多线程的支持。
  • 头文件:<thread>
  • 类:thread
  • 方法
    • get_id
    • join
    • detach:非常危险的命令,建议不用。特别注意主线程和子线程通过引用,智能指针传递了参数时,主线程退出,会造成变量回收,子线程处于不安全运行;或者通过隐式转换传递参数给子线程时,主线程退出后才执行参数转换,子线程无法正确获取到参数,处于不安全运行。
    • joinable
    • std::ref:传递对象引用进子线程函数,使主线程和子线程共享。
    • std::move:传递智能指针参数到线程函数。
  • 用线程方法创建线程:std::thread(thread_work,…)
  • 用类创建线程:类必须重载操作符(),void operator()()
  • 用类成员函数创建线程:std::thread(&A::thread_work,…)
  • 用lambda表达式创建线程

4. 互斥量

  • mutex,互斥锁是一个可锁的对象,它被设计成在关键的代码段需要独占访问时发出信号,从而阻止具有相同保护的其他线程并发执行并访问相同的内存位置。
  • recursive_mutex,递归互斥锁是一个可锁的对象,就像互斥一样,但是允许同一个线程获得对互斥对象的多个级别的所有权。
  • timed_mutex,定时的互斥信号是一个时间可锁定的对象,旨在当关键部分的代码需要独占访问时,就像一个普通互斥,但另外支持定时try-lock请求。
  • recursive_timed_mutex,一个递归的互斥对象结合的特点recursive_mutex timed_mutex到单个类的特性:它同时支持由一个线程获取多个锁级别也定时try-lock请求。
  • 头文件:<mutex>
  • 类:mutex,lock_guard,unique_lock(模板类)
  • 方法:lock、unlock
  • 死锁:两把或者更多锁,则可能造成死锁。解决死锁方案:1)保证上锁顺序一致,则不会死锁。2)使用std::lock(建议慎用或者不用),std::lock_guard+std::adopt_lock
  • unique_lock:可以取代lock_guard,但一般情况下lock_guard足够,unique_lock效率更低,内存占用更多
    • std::adopt_lock:互斥量必须先加锁
    • std::try_to_lock:互斥量不能先lock
    • std::defer_lock :互斥量不能先lock,初始化一个不加锁的互斥量,然后尝试自己lock,unlock,try_lock,relase(与互斥量解绑定,接管后必须手工解锁),但lock后可以不用调用unlock,unlock在析构时会被自动调用
    • unique_lock与mutex的所有权可以转让,使用std::move

5. 条件变量

  • 头文件:<condition_variable>
  • std::condition_variable
    • wait
    • wait_for
    • wait_util
    • notify_one
    • notify_all
  • std::condition_variable_any
  • std::notify_all_at_thread_exit

6. 异步任务

  • 头文件:<future>
  • std::future
  • std::shared_future
  • std::future_status
  • std::async:可以用全局函数,或者类成员函数作参数
  • std::packaged_task:包装任务,结合lambda表达式定义函数体,可以将包装对象放进容器
  • std::promise
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值