C++笔记-并发编程 异步任务(async)
转自 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)相关推荐
- 学习笔记(34):Python网络编程并发编程-异步调用与回调机制
立即学习:https://edu.csdn.net/course/play/24458/296452?utm_source=blogtoedu 1.知识点:(详细见代码注释) 1)同步调用: res1 ...
- Java并发编程实战笔记—— 并发编程1
1.如何创建并运行java线程 创建一个线程可以继承java的Thread类,或者实现Runnabe接口. public class thread {static class MyThread1 ex ...
- java task和thread_【Java学习笔记-并发编程】线程与任务
前言 最近在看一些Java15的并发.线程调度以及一些实现方案的东西,虽然很多东西还是 1.5 的,但还是很有收获. 一.线程与任务 Java中,要用线程来执行任务,线程可以说是任务的容器.没有线程的 ...
- Java并发编程之美读书笔记-并发编程基础2
2019独角兽企业重金招聘Python工程师标准>>> 1.线程的通知与等待 Java中的Object类是所有类的父亲,鉴于继承机制,Java把所有类都需要的方法放到了Object类 ...
- go语言学习笔记 — 并发编程 — 通道channel(3):各种各样的通道
3.1 单向通道 在声明通道时,我们可以设置只发送或只接收.这种被约束操作方向的通道称为单向通道. 声明单向通道 只发送:chan<-,只接收:<-chan var 通道实例 chan&l ...
- .NET Core 中的并发编程
今天我们购买的每台电脑都有一个多核心的 CPU,允许它并行执行多个指令.操作系统通过将进程调度到不同的内核来发挥这个结构的优点. 然而,还可以通过异步 I/O 操作和并行处理来帮助我们提高单个应用程序 ...
- 在 .NET Core 中的并发编程
原文地址:http://www.dotnetcurry.com/dotnet/1360/concurrent-programming-dotnet-core 今天我们购买的每台电脑都有一个多核心的 C ...
- [翻译]在 .NET Core 中的并发编程
原文地址:http://www.dotnetcurry.com/dotnet/1360/concurrent-programming-dotnet-core 今天我们购买的每台电脑都有一个多核心的 C ...
- 计算机笔记--【并发编程①】
文章目录 并发编程 前言 1.进程与线程 1.1.概述 1.2.对比 2.并行与并发 3.同步与异步 3.1.应用之异步调用 3.2.应用之提高效率 4.Java线程 4.1.创建和运行线程 4.2. ...
最新文章
- python 绘图脚本系列简单记录
- SpringBoot实现万能文件在线预览,已开源,真香!!!
- Django中Mysql数据库的使用
- mysql编译参数查看_查看 apache,nginx,mysql 安装时的编译参数
- linux文件读写实例,[Linux文件]使用read函数从文件读取数据的实例
- 协程 线程 进程的一点理解
- leetcode409.Longest Palindrome
- 在MonoTouch中正确而简单的使用 Sqlite 数据库
- mac osx 下的 mysql_Mac OSX下的MySQL数据库升级
- Lua开发工作笔记0001---什么是热更新为什么要热更
- 拉卡拉2020年股东净利润9.31亿 积极布局数字人民币业务
- 【计算机视觉-从入门到精通系列】 第一章 基础知识
- HDU 2841 容斥 或 反演
- python文本字符串比对_[Python] 利用HTML页面查看字符串差异
- Python如何做自动化测试?
- error: C++ preprocessor “/lib/cpp“ fails sanity check错误解决方法
- 深圳白领辞职开办“淘智网”
- 将LIBSVM用于多分类时根据svmtrain输出结果得到各OvO分类超平面的法向量w和偏移项b
- 百年奥运是一部科技史,智能奥运在平昌冬奥会浮出水面
- 福建职称计算机高级工程师评审,福建土建类评高级职称评审论文要求
热门文章
- 适合pythonpandas的软件_11个Python Pandas小技巧让你的工作更高效(附代码实例)
- .axf文件_ELF文件格式与readelf命令使用
- 计算机网络交换机组网及虚拟局域网实验报告,计算机网络实验报告材料(虚拟局域网).doc...
- [leetcode]5336. 上升下降字符串
- 试用 P、V操作描述下列理发师和顾客之间的同步问题
- 牛客网暑期ACM多校训练营(第三场): E. Sort String(KMP)
- Codeforces Round #467 (Div. 1): A. Save Energy!(公式)
- 经典问题:流水线调度(51nod)
- zabbix报警系统docker部署,k8s部署,基本使用方法
- vivado2018.3添加IP库