转自 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 = 0;
std::mutex g_i_mutex;  // 保护 g_ivoid 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: 0
140641306900224: 1
140641298507520: 2
main: 2

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...);

转载于:https://www.cnblogs.com/gnivor/p/9490167.html

C++笔记-并发编程 异步任务(async)相关推荐

  1. 学习笔记(34):Python网络编程并发编程-异步调用与回调机制

    立即学习:https://edu.csdn.net/course/play/24458/296452?utm_source=blogtoedu 1.知识点:(详细见代码注释) 1)同步调用: res1 ...

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

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

  3. java task和thread_【Java学习笔记-并发编程】线程与任务

    前言 最近在看一些Java15的并发.线程调度以及一些实现方案的东西,虽然很多东西还是 1.5 的,但还是很有收获. 一.线程与任务 Java中,要用线程来执行任务,线程可以说是任务的容器.没有线程的 ...

  4. Java并发编程之美读书笔记-并发编程基础2

    2019独角兽企业重金招聘Python工程师标准>>> 1.线程的通知与等待 Java中的Object类是所有类的父亲,鉴于继承机制,Java把所有类都需要的方法放到了Object类 ...

  5. go语言学习笔记 — 并发编程 — 通道channel(3):各种各样的通道

    3.1 单向通道 在声明通道时,我们可以设置只发送或只接收.这种被约束操作方向的通道称为单向通道. 声明单向通道 只发送:chan<-,只接收:<-chan var 通道实例 chan&l ...

  6. .NET Core 中的并发编程

    今天我们购买的每台电脑都有一个多核心的 CPU,允许它并行执行多个指令.操作系统通过将进程调度到不同的内核来发挥这个结构的优点. 然而,还可以通过异步 I/O 操作和并行处理来帮助我们提高单个应用程序 ...

  7. 在 .NET Core 中的并发编程

    原文地址:http://www.dotnetcurry.com/dotnet/1360/concurrent-programming-dotnet-core 今天我们购买的每台电脑都有一个多核心的 C ...

  8. [翻译]在 .NET Core 中的并发编程

    原文地址:http://www.dotnetcurry.com/dotnet/1360/concurrent-programming-dotnet-core 今天我们购买的每台电脑都有一个多核心的 C ...

  9. 计算机笔记--【并发编程①】

    文章目录 并发编程 前言 1.进程与线程 1.1.概述 1.2.对比 2.并行与并发 3.同步与异步 3.1.应用之异步调用 3.2.应用之提高效率 4.Java线程 4.1.创建和运行线程 4.2. ...

最新文章

  1. python 绘图脚本系列简单记录
  2. SpringBoot实现万能文件在线预览,已开源,真香!!!
  3. Django中Mysql数据库的使用
  4. mysql编译参数查看_查看 apache,nginx,mysql 安装时的编译参数
  5. linux文件读写实例,[Linux文件]使用read函数从文件读取数据的实例
  6. 协程 线程 进程的一点理解
  7. leetcode409.Longest Palindrome
  8. 在MonoTouch中正确而简单的使用 Sqlite 数据库
  9. mac osx 下的 mysql_Mac OSX下的MySQL数据库升级
  10. Lua开发工作笔记0001---什么是热更新为什么要热更
  11. 拉卡拉2020年股东净利润9.31亿 积极布局数字人民币业务
  12. 【计算机视觉-从入门到精通系列】 第一章 基础知识
  13. HDU 2841 容斥 或 反演
  14. python文本字符串比对_[Python] 利用HTML页面查看字符串差异
  15. Python如何做自动化测试?
  16. error: C++ preprocessor “/lib/cpp“ fails sanity check错误解决方法
  17. 深圳白领辞职开办“淘智网”
  18. 将LIBSVM用于多分类时根据svmtrain输出结果得到各OvO分类超平面的法向量w和偏移项b
  19. 百年奥运是一部科技史,智能奥运在平昌冬奥会浮出水面
  20. 福建职称计算机高级工程师评审,福建土建类评高级职称评审论文要求

热门文章

  1. 适合pythonpandas的软件_11个Python Pandas小技巧让你的工作更高效(附代码实例)
  2. .axf文件_ELF文件格式与readelf命令使用
  3. 计算机网络交换机组网及虚拟局域网实验报告,计算机网络实验报告材料(虚拟局域网).doc...
  4. [leetcode]5336. 上升下降字符串
  5. 试用 P、V操作描述下列理发师和顾客之间的同步问题
  6. 牛客网暑期ACM多校训练营(第三场): E. Sort String(KMP)
  7. Codeforces Round #467 (Div. 1): A. Save Energy!(公式)
  8. 经典问题:流水线调度(51nod)
  9. zabbix报警系统docker部署,k8s部署,基本使用方法
  10. vivado2018.3添加IP库