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

C++11异步任务轮子实现(header-only)

为什么写这个

  1. C++17异步任务需要future和promise配合使用,不是很喜欢那种语法。
  2. 实现一个操作简洁的异步任务。

满足功能

  1. 异步任务
  2. 超时控制
  3. get接口同步
  4. 任务计时
  5. lambda回调
  6. 任务重启

使用

#include "async_callback.h"
#include <unistd.h>
#include <iostream>
using namespace std;int main() {int a = 0, b = 0, c = 0;AsyncTask* task1 = new AsyncTask([&a](){sleep(2);for (int i = 0; i < 10000; ++i) {++a;}});AsyncTask* task2 = new AsyncTask([&b](){sleep(2);for (int i = 0; i < 10000; ++i) {++b;}});if (!task1->get(1)) {cout << "task1超时" << endl;}if (task2->get()) {cout << "task2没超时" << endl;}task1->restart();task2->restart();task1->get();task2->get();cout << a << endl;cout << b << endl;cout << "task1执行时间:" << task1->executionTime() << endl;cout << "task2执行时间:" << task2->executionTime() << endl;return 0;
}

打印结果:

task1超时
task2没超时
20000
20000
task1执行时间:2.00009
task2执行时间:2.00009

代码

// Simple asynchronous tasks with timeout
// Author: Y. F. Zhang
// Date: 2023-09-21#ifndef ASYNC_CALLBACK_H
#define ASYNC_CALLBACK_H#include <mutex>
#include <condition_variable>
#include <thread>
#include <atomic>
#include <functional>
#include <exception>
#include <iostream>
#include <sys/time.h>
#include <time.h>
class Timer {
public:Timer() {offsetTime_ = 0;timerState_ = TIMERSTOP;}void timerStart() {timerState_ = TIMERRUN;timeStamp_ = getWallTime();}double elapsedTime() {if (timerState_ == TIMERPAUSE) {return offsetTime_;}curTime_ = getWallTime() - timeStamp_ + offsetTime_;if (timerState_ == TIMERSTOP) return 0;return curTime_;}void pauseTimer() {offsetTime_ += getWallTime() - timeStamp_; timerState_ = TIMERPAUSE;}void stopTimer() {offsetTime_ = 0;curTime_ = 0;timerState_ = TIMERSTOP;}private:double getWallTime() {struct timeval time ;if (gettimeofday(&time,NULL)){return 0;}return (double)time.tv_sec + (double)time.tv_usec * .000001;}double timeStamp_;double curTime_;double offsetTime_;enum{TIMERSTOP,TIMERRUN,TIMERPAUSE} timerState_;
};namespace AsyncTaskException {class GetButTaskStopErr: public std::exception {const char* what() const throw () {return "invoke get method but task is stop!";}
};class GetExecutionTimeButTaskStopErr: public std::exception {const char* what() const throw () {return "invoke executionTime method but task is stop!";}
};}using func = std::function<void()>;
class AsyncTask {
private:enum {TASKRUNNING,TASKSTOP,TASKFINISHED} taskState_;func callback_;std::mutex mtx_;std::condition_variable cond_;std::atomic_bool completedFlag_;std::thread* taskThread_;Timer timer_;void initTask() {timer_.stopTimer();taskState_ = TASKSTOP;completedFlag_.store(false);if (taskThread_ != nullptr) {delete taskThread_;taskThread_ = nullptr;}}void runTask() {auto wrapperCallback = [this]() {try {timer_.timerStart();callback_();timer_.pauseTimer();completedFlag_.store(true);} catch (std::exception e) {fprintf(stderr, "%s", e.what());}taskState_ = TASKFINISHED;cond_.notify_one();};taskState_ = TASKRUNNING;taskThread_ = new std::thread(wrapperCallback);taskThread_->detach();}
public:AsyncTask(func&& callback) {this->callback_ = callback;restart();}void restart() {initTask();runTask();}double executionTime() {if (taskState_ == TASKSTOP) {throw AsyncTaskException::GetExecutionTimeButTaskStopErr();}return timer_.elapsedTime();}~AsyncTask() {if (taskThread_ != nullptr) {delete taskThread_;}}bool get(size_t timeoutSec = 0) {if (taskState_ == TASKSTOP) {throw AsyncTaskException::GetButTaskStopErr();}std::unique_lock<std::mutex> lk(mtx_);if (timeoutSec == 0) {cond_.wait(lk, [this](){return completedFlag_.load();});} else {return cond_.wait_for(lk, std::chrono::seconds(timeoutSec), [this](){return completedFlag_.load();});}return true;}};#endif

相关文章:

C++11异步任务轮子实现(header-only)

为什么写这个 C17异步任务需要future和promise配合使用&#xff0c;不是很喜欢那种语法。实现一个操作简洁的异步任务。 满足功能 异步任务超时控制get接口同步任务计时lambda回调任务重启 使用 #include "async_callback.h" #include <unistd.h> #includ…...

2023华为杯研究生数学建模竞赛选题建议+初步分析

如下为C君的2023华为杯研究生数学建模竞赛&#xff08;研赛&#xff09;选题建议初步分析 2023华为杯研究生数学建模竞赛&#xff08;研赛&#xff09;选题建议 提示&#xff1a;DS C君认为的难度&#xff1a;CE<D<F&#xff0c;开放度&#xff1a;CDE<F。 华为专项…...

多线程并发或线程安全问题如何解决

1、通过volatile关键字修饰变量&#xff0c;可以实现线程之间的可见性&#xff0c;避免变量脏读的出现&#xff0c;底层是通过限制jvm指令的重新排序实现的&#xff0c;适用于一个线程修改&#xff0c;多个线程读的场景。 2、通过synchronized锁&#xff08;任意对象&#xff0…...

深度学习——线性神经网络一

深度学习——线性神经网络一 文章目录 前言一、线性回归1.1. 线性回归的基本元素1.1.1. 线性模型1.1.2. 损失函数1.1.3. 解析解1.1.4. 随机梯度下降1.1.5. 用模型进行预测 1.2. 向量化加速1.3. 正态分布与平方损失1.4. 从线性回归到深度网络 二、线性回归的从零开始实现2.1. 生…...

利用大模型知识图谱技术,告别繁重文案,实现非结构化数据高效管理

我&#xff0c;作为一名产品经理&#xff0c;对文案工作可以说是又爱又恨&#xff0c;爱的是文档作为嘴替&#xff0c;可以事事展开揉碎讲清道明&#xff1b;恨的是只有一个脑子一双手&#xff0c;想一边澄清需求一边推广宣传一边发布版本一边申报认证实在是分身乏术&#xff0…...

Java抽象类和普通类区别、 数组跟List的区别

抽象类 Java中的抽象类是一种特殊的类&#xff0c;它不能被实例化&#xff0c;只能被继承。抽象类通常用于定义一些通用的属性和方法&#xff0c;但是这些方法的具体实现需要在子类中完成。抽象类中可以包含抽象方法和非抽象方法。 抽象方法是一种没有实现的方法&#xff0c;…...

Leetcode.2522 将字符串分割成值不超过 K 的子字符串

题目链接 Leetcode.2522 将字符串分割成值不超过 K 的子字符串 rating : 1605 题目描述 给你一个字符串 s s s &#xff0c;它每一位都是 1 1 1 到 9 9 9 之间的数字组成&#xff0c;同时给你一个整数 k k k 。 如果一个字符串 s s s 的分割满足以下条件&#xff0c;我们…...

成绩分析(蓝桥杯)

成绩分析 题目描述 小蓝给学生们组织了一场考试&#xff0c;卷面总分为 100 分&#xff0c;每个学生的得分都是一个 0 到 100 的整数。 请计算这次考试的最高分、最低分和平均分。 输入描述 输入的第一行包含一个整数 n (1≤n≤104 )&#xff0c;表示考试人数。 接下来 n 行…...

【多思路附源码持续更新】2023年华为杯(中国研究生数学建模)竞赛C题

赛题 若官网拥挤&#xff0c;数据集和赛题下载地址如下&#xff1a; https://download.csdn.net/download/weixin_47723732/88364777 历届优秀论文下载地址&#xff0c;可以做参考文章 https://download.csdn.net/download/weixin_47723732/88365222 论文万能模板下载地址 htt…...

基于STM32设计的校园一卡通(设计配套的手机APP)

一、功能介绍 【1】项目介绍 随着信息技术的不断发展,校园一卡通作为一种高效便捷的管理方式,已经得到了广泛的应用。而其核心部件——智能卡也被越来越多的使用者所熟知。 本文介绍的项目是基于STM32设计的校园一卡通消费系统,通过RC522模块实现对IC卡的读写操作,利用2…...

有了Spring为什么还需要SpringBoot呢

目录 一、Spring缺点分析 二、什么是Spring Boot 三、Spring Boot的核心功能 3.1 起步依赖 3.2 自动装配 一、Spring缺点分析 1. 配置文件和依赖太多了&#xff01;&#xff01;&#xff01; spring是一个非常优秀的轻量级框架&#xff0c;以IOC&#xff08;控制反转&…...

【记录】Python 之于 C/C++ 区别

记录本人在 Python 上经常写错的一些地方&#xff08;C/C 写多了&#xff0c;再写 Python 有点切换不过来&#xff09; 逻辑判断符号用 and、or、!可以直接 10 < num < 30 比较大小分支语句&#xff1a;if、elif、else使用 、-&#xff0c;Python 中不支持 、- - 这两个…...

【Vue-Element-Admin】dialog关闭回调事件

背景 点击导入按钮&#xff0c;调出导入弹窗&#xff0c;解析excel数据后&#xff0c;不点击【确认并导入】按钮&#xff0c;直接关闭弹窗&#xff0c;数据违背清理 实现 使用dialog的close回调函数&#xff0c;在el-dialog添加close&#xff0c;在methods中定义closeDialog…...

Ansible自动化:简化你的运维任务

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

webpack配置alias后eslint和ts无法识别

背景 我们在 webpack 配置 alias 后&#xff0c;发现项目中引入的时候&#xff0c;还是会报错&#xff0c;如下&#xff1a; 可以看到&#xff0c;有一个是 ts报错&#xff0c;还有一个是 eslint 报错。 解决 ts 报错 tsconfig.json {"compilerOptions": {...&q…...

小程序从无到有教学教程-- 01.重置华为云服务器Huawei Cloud EulerOS 2.0版本并且设置安全组

概述 专门拿了专栏来讲解&#xff0c;所以目录结构就比较简单了 文章目录 概述修改华为云操作系统选择Huawei Cloud EulerOS 2.0 镜像顺便配置华为安全组 修改华为云操作系统 这里选择华为最新的系统&#xff0c;不过也就2.0~ 选择Huawei Cloud EulerOS 2.0 镜像 这里记住密…...

js实现短信验证码一键登录

前言 短信验证码一键登录是一种方便快捷的登录方式&#xff0c;用户只需输入手机号码&#xff0c;然后接收到手机短信验证码并自动填入验证码框&#xff0c;即可完成登录操作。本文将介绍短信验证码一键登录的原理&#xff0c;并给出一个简单的示例说明。 短信验证码一键登录…...

vue2的基础知识巩固

一、定义&#xff1a;是一个渐进式的JavaScript框架 二、特点&#xff1a; 减少了大量的DOM操作编写 &#xff0c;可以更专注于逻辑操作分离数据和界面的呈现&#xff0c;降低了代码耦合度(前端端分离)支持组件化开发&#xff0c;更利于中大型项目的代码组织 vue2核心功能&a…...

echart离线地图下载地址

链接: 离线地图地址 https://datav.aliyun.com/portal/school/atlas/area_selector...

elk日志某个时间节点突然搜索不到了

elk日志某个时间节点突然搜索不到了,检查filebeat正常 Kibana手动上传数据: 响应: Error: Validation Failed: 1: this action would add [2] total shards, but this cluster currently has [2000]/[2000] maximum shards open 原因:ElasticSearch总分片数量导致的异常,ES…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...