转自 https://www.cnblogs.com/diysoul/p/5937075.html

参考:https://zh.cppreference.com/w/cpp/thread/lock_guard

创建 lock_guard 对象时,它试图接收给定互斥的所有权。控制离开创建 lock_guard 对象的作用域时,销毁 lock_guard 并释放互斥。

lock_guard 类不可复制。

模板形参

Mutex - 要锁定的互斥。类型必须满足基础可锁 (BasicLockable) 要求

成员类型

 
成员类型 定义
mutex_type Mutex

成员函数

构造 lock_guard ,可选地锁定给定的互斥 
(公开成员函数)
析构 lock_guard 对象,解锁底层互斥 
(公开成员函数)
operator=
[被删除]
不可复制赋值 
(公开成员函数)

示例

运行此代码
#include <thread>
#include <mutex>
#include <iostream> int g_i = ;
std::mutex g_i_mutex; // 保护 g_i void safe_increment()
{
std::lock_guard<std::mutex> lock(g_i_mutex);
++g_i; std::cout << std::this_thread::get_id() << ": " << g_i << '\n'; // g_i_mutex 在锁离开作用域时自动释放
} int main()
{
std::cout << "main: " << g_i << '\n'; std::thread t1(safe_increment);
std::thread t2(safe_increment); t1.join();
t2.join(); std::cout << "main: " << g_i << '\n';
}

可能的输出:

main:
:
:
main:

C++并发编程 异步任务(async)

线程基本的互斥和同步工具类, 主要包括:
  std::mutex 类
  std::recursive_mutex 类
  std::timed_mutex 类
  std::recursive_timed_mutex 类
  std::lock_guard 类型模板
  std::unique_lock 类型模板
  std::lock 函数模板
  std::once_flag 类
  std::call_once 函数模板

std::mutex 类

  std::mutex 上锁须要调用 lock() 或 try_lock(), 当有一个线程获取了锁, 其它线程想要取得此对象的锁时, 会被阻塞(lock)或失败(try_lock). 当线程完成共享数据的保护后, 需要调用 unlock 进行释放锁.
  std::mutex 不支嵌套, 如果两次调用 lock, 会产生未定义行为.

std::recursive_mutex 类

使用方法同 std::mutex, 但 std::recursive_mutex 支持一个线程获取同一个互斥量多次,而没有对其进行一次释放. 但是同一个线程内, lock 与 unlock 次数要相等, 否则其它线程将不能取得任何机会.
其原理是, 调用 lock 时, 当调用线程已持有锁时, 计数加1; 调用 try_lock 时, 尝试取得锁, 失败时不会阻塞, 成功时计数加1; 调用 unlock 时, 计数减1, 如果是最后一个锁时, 释放锁.
需要注意的是: 调用 try_lock时, 如果当前线程未取得锁, 即使没有别的线程取得锁, 也有可能失败.

std::timed_mutex 类

std::timed_mutex 在 std::mutex 的基础上支持让锁超时. 上锁时可以调用 try_lock_for, try_lock_until 设置超时值.
try_lock_for 的参数是需要等待的时间, 当参数小于等于0时会立即返回, 效果和使用 try_lock 一样. 
try_lock_until 传入的参数不能小于当前时间, 否则会立即返回, 效果和使用 try_lock 一样. 实际上 try_lock_for 内部也是调用 try_lock_until 实现的.
tm.try_lock_for(std::chrono::milliseconds(1000)) 与 tm.try_lock_until(std::chrono::steady_clock::now() + std::chrono::milliseconds(1000)) 等价, 都是等待1s.

std::recursive_timed_mutex 类

std::recursive_timed_mutex 在 std::recursive_mutex 的基础上, 让锁支持超时.
用法同 std::timed_mutex, 超时原理同 std::recursive_mutex.

std::lock_guard 类型模板

std::lock_guard 类型模板为基础锁包装所有权. 指定的互斥量在构造函数中上锁, 在析构函数中解锁.
这就为互斥量锁部分代码提供了一个简单的方式: 当程序运行完成时, 阻塞解除, 互斥量解锁(无论是执行到最后, 还是通过控制流语句break或return, 亦或是抛出异常).
std::lock_guard 不支持拷贝构造, 拷贝赋值和移动构造.

std::unique_lock 类型模板

std::unique_lock 类型模板比 std::loc_guard 提供了更通用的所有权包装器.
std::unique_lock 可以调用 unlock 释放锁, 而后当再次需要对共享数据进行访问时再调用 lock(), 但是必须注意一次 lock 对应一次 unlock, 不能连续多次调用同一个 lock 或 unlock.
std::unique_lock 不支持拷贝构造和拷贝赋值, 但是支持移动构造和移动赋值.
std::unique_lock 比 std::loc_guard 还增加了另外几种构造方式:
unique_lock(_Mutex& _Mtx, adopt_lock_t) 构建持有锁实例, 其不会调用 lock 或 try_lock, 但析构时默认会调用 unlock.
unique_lock(_Mutex& _Mtx, defer_lock_t) 构建非持有锁实例, 其不会调用 lock 或 try_lock, 如果没有使用 std::lock 等函数修改标志, 析构时也不会调用 unlock.
unique_lock(_Mutex& _Mtx, try_to_lock_t) 尝试从互斥量上获取锁, 通过调用 try_lock
unique_lock(_Mutex& _Mtx, const chrono::duration<_Rep, _Period>& _Rel_time) 在给定时间长度内尝试获取锁
unique_lock(_Mutex& _Mtx, const chrono::time_point<_Clock, _Duration>& _Abs_time) 在给定时间点内尝试获取锁
bool owns_lock() const 检查是否拥有一个互斥量上的锁

std::lock 函数模板

std::lock 函数模板提供同时锁住多个互斥量的功能, 且不会有因改变锁的一致性而导致的死锁. 其声明如下:
template<typename LockableType1,typename... LockableType2> void lock(LockableType1& m1,LockableType2& m2...);

C++笔记-并发编程 异步任务(async)的更多相关文章

  1. C++并发编程 异步任务

    C++并发编程 异步任务 异步任务 std::async (1) std::async 会返回一个 std::future 对象, 这个对象持有最终计算出来的结果. 当需要这个值时, 只需要调用对象的 ...

  2. C# 并发编程 (异步编程与多线程)

    并发:同时做多件事情 多线程:并发的一种形式,它采用多个线程来执行程序. 并行处理:把正在执行的大量的任务分割成小块,分配给多个同时运行的线程.并行处理是多线程的一种,而多线程是并发的一种. 异步编程 ...

  3. csapp读书笔记-并发编程

    这是基础,理解不能有偏差 如果线程/进程的逻辑控制流在时间上重叠,那么就是并发的.我们可以将并发看成是一种os内核用来运行多个应用程序的实例,但是并发不仅在内核,在应用程序中的角色也很重要. 在应用级 ...

  4. Java并发编程实战笔记—— 并发编程1

    1.如何创建并运行java线程 创建一个线程可以继承java的Thread类,或者实现Runnabe接口. public class thread { static class MyThread1 e ...

  5. Java并发编程实战笔记—— 并发编程4

    1.同步容器类 同步容器类都是线程安全的,但在某些情况下可能需要额外的客户端加锁保护复合操作. 容器上常见的复合操作包括但不限于:迭代(反复访问数据,直到遍历完容器中所有的元素为止).跳转(根据指定顺 ...

  6. Java并发编程实战笔记—— 并发编程2

    1.ThreadLocal Java中的ThreadLocal类可以让你创建的变量只被同一个线程进行读和写操作.因此,尽管有两个线程同时执行一段相同的代码,而且这段代码又有一个指向同一个ThreadL ...

  7. python 并发编程 异步IO模型

    异步IO(Asynchronous I/O) Linux下的asynchronous IO其实用得不多,从内核2.6版本才开始引入.先看一下它的流程: 用户进程发起read操作之后,立刻就可以开始去做 ...

  8. Java并发编程实战笔记—— 并发编程3

    1.实例封闭 class personset{ private final Set<Person> myset = new HashSet<Person>(); public ...

  9. C++并发编程 互斥和同步

    C++并发编程 异步任务(async) 线程基本的互斥和同步工具类, 主要包括: std::mutex 类 std::recursive_mutex 类 std::timed_mutex 类 std: ...

随机推荐

  1. Netty源码分析(四):EventLoopGroup

    无论服务端或客户端启动时都用到了NioEventLoopGroup,从名字就可以看出来它是NioEventLoop的组合,是Netty多线程的基石. 类结构 NioEventLoopGroup继承自M ...

  2. kernel pwn 入门环境搭建

    刚开始上手kernel pwn,光环境就搭了好几天,应该是我太菜了.. 好下面进入正题,环境总共就由两部分构成,qemu和gdb.这两个最好都需要使用源码安装. 我使用的安装环境为 qemu:安装前要 ...

  3. 让老板虎躯一震的前端技术,KPI杀手

    本文由云+社区发表 作者:思衍Jax 天下武功,唯 (wei) 快(fu) 不(bu) 破(po). 随着近几年的前端技术的高速发展,越来越多的团队使用 React.Vue 等 SPA 框架作为其主要 ...

  4. 痞子衡嵌入式:ARM Cortex-M内核那些事(5)- 指令集

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是ARM Cortex-M指令集. 指令集 指令长度(bits) 包含指令 CortexM0 CortexM0+ CortexM1 Cor ...

  5. AlwaysUp使用方法

    AlwaysUp是一款能将可执行文件.批处理文件及快捷方式作为Windows系统服务,并且进行管理和监视确保100%运行.当程序崩溃.挂起.弹出错误对话框时,AlwaysUp 能自动重启程序,并运行自 ...

  6. STM32-FreeRTOS快速学习之总结1

    1. 基础知识注意:在RTOS中是优先值越高则优先级越高(和ucos/linux的相反) 在移植的时候,主要裁剪FreeRTOS/Source/portable文件夹,该文件夹用来针对不同MCU做的一 ...

  7. Java开发笔记(三十八)利用正则表达式校验字符串

    前面多次提到了正则串.正则表达式,那么正则表达式究竟是符合什么定义的字符串呢?正则表达式是编程语言处理字符串格式的一种逻辑式子,它利用若干保留字符定义了形形色色的匹配规则,从而通过一个式子来覆盖满足了 ...

  8. Dynamics 365中配置和使用文件夹级别的跟踪(folder-level tracking)

    本人微信和易信公众号:微软动态CRM专家罗勇 ,回复274或者20180630可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong.me ...

  9. java中的sql语句中如果有like怎么写

    我先是在SQL server中写了如下语句: 这样是顺利执行的,可是我把这句话复制到Java代码中打出来却报错了, 刚开始我还以为是前端没有传回来值,待我一句一句打印发现,它提示我rs没有next.到 ...

  10. MySQL 修改账号的IP限制条件

    今天遇到一个需求:修改MySQL用户的权限,需要限制特定IP地址才能访问,第一次遇到这类需求,结果在测试过程,使用更新系统权限报发现出现了一些问题, 具体演示如下. 下面测试环境为MySQL 5.6. ...