当前位置: 首页 > news >正文

C++11 std::async推荐使用 std::launch::async 模式

async真假多线程

std::launch::async真多线程

std::launch::async | std::launch::deferred可能多线程

std::launch::deferred假多线程

枚举变量说明

枚举定义

enum class launch
{async = 1,                  // 0b1deferred = 2,               // 0b10any = async | deferred      // 0b11
};

std::launch::async: 一定在另一个线程跑函数

std::launch::deferred: get,wait代码所在线程跑函数;

即调用get,wait的时候再串行执行函数; 如果不调用则不执行;

默认: any

即默认可能延迟, 也可能立即执行; 跟系统当时的负载均衡, 超限等方面的阈值决定, 采取延迟还是立即执行;

默认机制的问题std::launch::any

案例

void t() {auto fut = std::async(f);   // run f using default launch policy
}

问题: 不确定性

  • f, t可能在一个线程执行, 也可能在不同的线程执行;
  • fut.get|fut.wait, f这两个也可能在一个线程, 也可能不在一个线程;
  • f可能在执行, 可能不在执行;

影响数据: TLS:thread local storage

thread_local修饰的可能会新创建, 也可能不创建; 就有很大的问题;

影响逻辑: wait问题

auto fut = std::async(f);while (fut.wait_for(100ms) != std::future_status::ready) {
}
enum class future_status {ready,timeout,deferred
};

f可能永远也没有执行; fut的状态永远是deferred; 永远循环下去;

这种可能漏洞可能永远也不会触发, 因为即使是压测或其他测试, 测试环境可能永远也不会出现; 但是在一些极端环境就啃根出现;

影响逻辑: 规避方案

wait_for(0)状态查询;

auto fut = std::async(f);if (fut.wait_for(0) != std::future_status::deferred) {// do something and return;// ...use wait or get on fut to call f synchronously
} else {while (fut.wait_for(100ms) != std::future_status::deferred) {// task is neither deferred nor ready, so do concurrent work until it's ready}// now is ready.
}

default使用条件

  • f不用和get,wait调用者所在线程并行;
  • 不关注thread_local变量的线程安全;
  • 接受函数执行和不执行的代价; 接受get,wait时阻塞执行; 接受不调用get, wait不执行;
  • 考虑到了延迟执行的情况和代价;

一定多线程

std::launch::async

auto fut = std::async(std::launch::async, f);

默认std::launch::async: c++11

template<typename F, typename... Ts>
inline
std::future<typename std::result_of<F(Ts...)>::type>
reallyAsync(F&& f, Ts&&... params) // return future
{// for asynchronous // call to f(params...)return std::async(std::launch::async,std::forward<F>(f), std::forward<Ts> (params)...);
}

默认std::launch::async: c++14

template<typename F, typename... Ts>
inline
auto
reallyAsync(F&& f, Ts&&... params) // return future
{// for asynchronous // call to f(params...)return std::async(std::launch::async,std::forward<F>(f), std::forward<Ts> (params)...);
}

差异: c++11不支持返回值类型推理;

总结

默认: deferred + async的结合, 行为未知, 大多数异步;

默认影响: thread_local, 任务不执行, wait无限等待;

std::launch::async强制多线程;

http://www.lryc.cn/news/132309.html

相关文章:

  • 没有使用springboot 单独使用spring-boot-starter-logging
  • 创建Azure资源锁
  • 卷积神经网络教程 (CNN) – 使用 TensorFlow 在 Python 中开发图像分类器
  • MyBatis XML映射处理CLOB和BLOB类型
  • FPGA_学习_14_第一个自写模块的感悟和ila在线调试教程与技巧(寻找APD的击穿偏压)
  • 【2023新教程】树莓派定时自动拍照并上传腾讯云对象存储COS
  • 校企合作谋发展 合作共赢谱新篇|云畅科技与湖南民族职业学院签订校企合作协议
  • vue技术学习
  • 基于空间的图卷积神经网络:GNN
  • .net core发布到IIS上出现 HTTP 错误 500.19
  • 01_Redis单线程与多线程
  • 机器学习——随机森林【手动代码】
  • Vue 2 处理边界情况
  • 写一个mysql 正则表达式,每三个img标签图片后面添加<hr>
  • Spring MVC异常处理
  • Centos7安装docker后默认开启docker0的网卡|卸载默认网卡
  • 04_Redis与mysql数据双写一致性案例
  • vue的开发者工具下载『保姆级别』
  • vue的scrollTop手机环境设置值失效,本地正常可以赋值
  • [前端系列第7弹]Vue:一个渐进式的 JavaScript 框架
  • C#键盘按键对应Keys类大全
  • SpringBoot 学习(03): 弱语言的注解和SpringBoot注解的异同
  • CloudQuery:更好地管理你的 OceanBase 数据库
  • php的password_verify 和 password_hash密码验证
  • JAVA免杀学习与实验
  • Apche Kafka + Spring的消息监听容器
  • [JavaWeb]【五】web后端开发-Tomcat SpringBoot解析
  • css 用过渡实现,鼠标离开li时,背景色缓慢消息的样式
  • pytorch 线性层Linear详解
  • LeetCode 833. 字符串中的查找与替换