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 = ;
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)的更多相关文章
- C++并发编程 异步任务
C++并发编程 异步任务 异步任务 std::async (1) std::async 会返回一个 std::future 对象, 这个对象持有最终计算出来的结果. 当需要这个值时, 只需要调用对象的 ...
- C# 并发编程 (异步编程与多线程)
并发:同时做多件事情 多线程:并发的一种形式,它采用多个线程来执行程序. 并行处理:把正在执行的大量的任务分割成小块,分配给多个同时运行的线程.并行处理是多线程的一种,而多线程是并发的一种. 异步编程 ...
- csapp读书笔记-并发编程
这是基础,理解不能有偏差 如果线程/进程的逻辑控制流在时间上重叠,那么就是并发的.我们可以将并发看成是一种os内核用来运行多个应用程序的实例,但是并发不仅在内核,在应用程序中的角色也很重要. 在应用级 ...
- Java并发编程实战笔记—— 并发编程1
1.如何创建并运行java线程 创建一个线程可以继承java的Thread类,或者实现Runnabe接口. public class thread { static class MyThread1 e ...
- Java并发编程实战笔记—— 并发编程4
1.同步容器类 同步容器类都是线程安全的,但在某些情况下可能需要额外的客户端加锁保护复合操作. 容器上常见的复合操作包括但不限于:迭代(反复访问数据,直到遍历完容器中所有的元素为止).跳转(根据指定顺 ...
- Java并发编程实战笔记—— 并发编程2
1.ThreadLocal Java中的ThreadLocal类可以让你创建的变量只被同一个线程进行读和写操作.因此,尽管有两个线程同时执行一段相同的代码,而且这段代码又有一个指向同一个ThreadL ...
- python 并发编程 异步IO模型
异步IO(Asynchronous I/O) Linux下的asynchronous IO其实用得不多,从内核2.6版本才开始引入.先看一下它的流程: 用户进程发起read操作之后,立刻就可以开始去做 ...
- Java并发编程实战笔记—— 并发编程3
1.实例封闭 class personset{ private final Set<Person> myset = new HashSet<Person>(); public ...
- C++并发编程 互斥和同步
C++并发编程 异步任务(async) 线程基本的互斥和同步工具类, 主要包括: std::mutex 类 std::recursive_mutex 类 std::timed_mutex 类 std: ...
随机推荐
- 使用开源项目Alipay.AopSdk.Core完成支付宝网页登录
核心方法: public IActionResult UserInfoCallBackAli() { var alipayClient = new DefaultAopClient(ConfigAli ...
- Tomcat多实例部署
前言 以前总是采用很Low的方式太同一台服务器上部署多个Web应用,步骤是这样的:Copy Tomcat目录-->更改conf/server.xml三个端口号----->部署war包--- ...
- lua的String
基础字符串函数 字符串库中有一些函数非常简单,如: 1). string.len(s) 返回字符串s的长度: 2). string.rep(s,n) 返回字符串s重复n次的结果: 3 ...
- js密码修改显示与隐藏效果
一.添加input框 <form class="login_form"> <input class="password inputpwd" i ...
- Java 使用Arrays.sort排序 从大到小排列
前言 一般情况,我们在Java中给数组排序,比起自己写个冒泡排序,更加喜欢使用Java中自带的sort方法,也就是Arrays.sort方法 但是,这个方法只会将数组从小到大排列,如果我们需要从大到小 ...
- rocketmq 发送时异常:system busy 和 broker busy 解决方案
记一次 rocketmq 使用时的异常. 这里就不说什么rocketmq 源码啥的了,因为没看过.网上一搜这两个异常 大部分都是什么源码解读,也没说出现后的解决办法(蓝瘦香菇). 大量测试发现: 1. ...
- Spring笔记01_下载_概述_监听器
目录 Spring笔记01 1.Spring介绍 1.1 Spring概述 1.2 Spring好处 1.3 Spring结构体系 1.4 在项目中的架构 1.5 程序的耦合和解耦 2. Spring ...
- java开发环境配置——IDEA SVN的使用
一.安装svn客户端,在idea中配置svn 装小乌龟,TortoiseSVN ,就下图一个要注意的地方,这里默认 command line client tools是不安装的,选上.如果已经安装过了 ...
- javascript进阶之AJAX
AJAX 一 AJAX预备知识:json进阶 1.1 什么是JSON? JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.JSON是用字符串来表示Javas ...
- CSS实现单行、多行文本超出部分显示省略号
单行文本超出,代码如下: css代码: <style> .one{ width:200px; overflow: hidden; text-overflow:ellipsis; whit ...