如何做花店网站/怎么注册网站 个人
文章目录
- 1. 线程池概述
- 线程池的基本特点:
- 2. 使用线程池的优先队列定时器实现
- 2.1 优先队列定时器实现
- 2.2 解释:
- 3. 使用时间轮的线程池定时器实现
- 3.1 时间轮定时器实现
- 4. 总结
在定时器设计中,使用线程池来执行定时任务可以有效提高程序的性能和可扩展性。线程池能够避免频繁创建和销毁线程的开销,并且通过重用线程来提高任务调度的效率。本文将介绍如何结合线程池和定时器来实现一个高效的定时任务调度系统。
我们将基于两种常见的定时器实现方式——优先队列 和 时间轮,使用线程池来执行定时任务,并分析每种实现方式的优缺点。
1. 线程池概述
线程池是一种管理多个线程的机制,避免了每次执行任务时创建和销毁线程的开销。线程池会预先创建一定数量的线程,并将任务提交给线程池执行。线程池中的线程会从任务队列中取出任务并执行,直到任务完成。
线程池的基本特点:
- 线程复用:线程池中的线程在任务执行完成后不会退出,而是继续等待下一个任务。
- 任务排队:任务被放入任务队列,线程池中的线程按顺序执行任务。
- 线程池大小控制:可以设置线程池的大小,避免线程过多或过少导致系统性能下降。
2. 使用线程池的优先队列定时器实现
在优先队列定时器中,使用线程池来执行定时任务,可以提高任务的执行效率。我们将在定时器任务到期时将任务提交到线程池执行,线程池会负责管理任务的执行。
2.1 优先队列定时器实现
#include <iostream>
#include <queue>
#include <functional>
#include <chrono>
#include <thread>
#include <vector>
#include <mutex>
#include <condition_variable>using namespace std;
using namespace std::chrono;// 定时任务结构体
struct TimerTask {steady_clock::time_point expiration_time; // 任务到期时间function<void()> callback; // 任务回调函数bool repeat; // 是否是周期性任务milliseconds interval; // 周期性任务间隔bool operator>(const TimerTask& other) const {return expiration_time > other.expiration_time;}
};// 线程池实现
class ThreadPool {
private:vector<thread> workers; // 线程池中的工作线程queue<function<void()>> tasks; // 任务队列mutex tasks_mutex; // 任务队列的互斥锁condition_variable cv; // 条件变量bool stop; // 是否停止线程池public:ThreadPool(size_t num_threads) : stop(false) {for (size_t i = 0; i < num_threads; ++i) {workers.emplace_back([this] {while (true) {function<void()> task;{unique_lock<mutex> lock(tasks_mutex);cv.wait(lock, [this] { return !tasks.empty() || stop; });if (stop && tasks.empty()) return; // 如果线程池被停止且任务队列为空,则退出task = move(tasks.front());tasks.pop();}task(); // 执行任务}});}}~ThreadPool() {{unique_lock<mutex> lock(tasks_mutex);stop = true;}cv.notify_all();for (thread& worker : workers) {if (worker.joinable()) {worker.join();}}}// 提交任务到线程池void submit(function<void()> task) {{unique_lock<mutex> lock(tasks_mutex);tasks.push(task);}cv.notify_one();}
};// 定时器管理类
class TimerManager {
private:priority_queue<TimerTask, vector<TimerTask>, greater<TimerTask>> task_queue; // 使用优先队列存储定时任务ThreadPool thread_pool; // 线程池bool running; // 是否正在运行定时器public:TimerManager(size_t num_threads) : thread_pool(num_threads), running(false) {}// 添加定时任务void addTask(function<void()> callback, milliseconds delay, bool repeat = false, milliseconds interval = milliseconds(0)) {TimerTask task;task.expiration_time = steady_clock::now() + delay;task.callback = callback;task.repeat = repeat;task.interval = interval;task_queue.push(task);}// 启动定时器void start() {running = true;while (running) {if (!task_queue.empty()) {TimerTask task = task_queue.top();auto now = steady_clock::now();if (now >= task.expiration_time) {task.callback(); // 执行任务task_queue.pop();// 如果是周期性任务,重新设置到期时间并将任务重新加入队列if (task.repeat) {task.expiration_time = now + task.interval;task_queue.push(task);}}}this_thread::sleep_for(milliseconds(10)); // 防止CPU占用过高}}// 停止定时器void stop() {running = false;}
};// 使用示例
int main() {TimerManager timerManager(4); // 使用4个线程的线程池// 添加一个定时任务,2秒后执行一次timerManager.addTask([]() { cout << "Task 1 executed!" << endl; }, milliseconds(2000));// 添加一个周期性任务,每3秒执行一次timerManager.addTask([]() { cout << "Periodic Task executed!" << endl; }, milliseconds(3000), true, milliseconds(3000));timerManager.start(); // 启动定时器return 0;
}
2.2 解释:
ThreadPool
类实现了一个简单的线程池,任务被放入队列,工作线程从队列中取任务并执行。- 在
TimerManager
中,定时任务到期时,任务会被提交到线程池执行。线程池通过并发执行任务来提高效率。 addTask
方法用于添加定时任务,周期性任务会在执行完后重新加入队列。
3. 使用时间轮的线程池定时器实现
时间轮定时器使用时间轮的结构来管理定时任务,每个时间轮槽存储一些任务。当时间轮滑动时,任务会按照设定的到期时间被执行。
3.1 时间轮定时器实现
#include <iostream>
#include <vector>
#include <deque>
#include <chrono>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>using namespace std;
using namespace std::chrono;struct TimerTask {steady_clock::time_point expiration_time; // 任务到期时间function<void()> callback; // 任务回调函数bool operator>(const TimerTask& other) const {return expiration_time > other.expiration_time;}
};// 线程池实现
class ThreadPool {
private:vector<thread> workers;queue<function<void()>> tasks;mutex tasks_mutex;condition_variable cv;bool stop;public:ThreadPool(size_t num_threads) : stop(false) {for (size_t i = 0; i < num_threads; ++i) {workers.emplace_back([this] {while (true) {function<void()> task;{unique_lock<mutex> lock(tasks_mutex);cv.wait(lock, [this] { return !tasks.empty() || stop; });if (stop && tasks.empty()) return;task = move(tasks.front());tasks.pop();}task();}});}}~ThreadPool() {{unique_lock<mutex> lock(tasks_mutex);stop = true;}cv.notify_all();for (thread& worker : workers) {if (worker.joinable()) {worker.join();}}}void submit(function<void()> task) {{unique_lock<mutex> lock(tasks_mutex);tasks.push(task);}cv.notify_one();}
};// 时间轮定时器
class TimeWheel {
private:vector<deque<TimerTask>> slots;int current_slot;milliseconds tick_interval;ThreadPool thread_pool;public:TimeWheel(int num_slots, milliseconds interval, size_t num_threads): current_slot(0), tick_interval(interval), thread_pool(num_threads) {slots.resize(num_slots);}void addTask(function<void()> callback, milliseconds delay) {TimerTask task;task.expiration_time = steady_clock::now() + delay;int slot_index = (duration_cast<milliseconds>(task.expiration_time.time_since_epoch()) / tick_interval) % slots.size();slots[slot_index].push_back(task);}void start() {while (true) {this_thread::sleep_for(tick_interval);auto now = steady_clock::now();for (auto& task : slots[current_slot]) {if (task.expiration_time <= now) {thread_pool.submit(task.callback);}}slots[current_slot].clear();current_slot = (current_slot +1) % slots.size();}}
};// 使用示例
int main() {TimeWheel timeWheel(10, milliseconds(1000), 4); // 10个槽,每个槽代表1秒,线程池使用4个线程timeWheel.addTask([]() { cout << "Task 1 executed!" << endl; }, milliseconds(3000));timeWheel.start(); // 启动时间轮return 0;
}
4. 总结
通过使用线程池,我们能够将定时任务的执行并发化,避免每个任务都新建一个线程的性能开销。优先队列和时间轮两种实现方式各有优缺点:
- 优先队列 定时器适用于任务数量较少、任务到期时间不均匀的场景,能够较好地处理动态任务调度。
- 时间轮 定时器适用于任务数量较多且时间间隔均匀的场景,尤其在高并发任务调度时表现优越。
通过结合线程池和定时器设计,可以实现高效、可扩展的定时任务调度系统,满足各种业务需求。
提示:更多内容可以访问Clang’s Blog:https://www.clang.asia
相关文章:

深入理解定时器:优先队列与时间轮实现
文章目录 1. 线程池概述线程池的基本特点: 2. 使用线程池的优先队列定时器实现2.1 优先队列定时器实现2.2 解释: 3. 使用时间轮的线程池定时器实现3.1 时间轮定时器实现 4. 总结 在定时器设计中,使用线程池来执行定时任务可以有效提高程序的性…...

autogen-agentchat 0.4.0.dev8版本的安装
1. 安装命令 pip install autogen-agentchat0.4.0.dev8 autogen-ext[openai]0.4.0.dev82. 版本检查 import autogen_agentchat print(autogen_agentchat.__version__)0.4.0.dev8import autogen_ext print(autogen_ext.__version__)0.4.0.dev83. 第一个案例 使用 autogen-age…...

JAVA |日常开发中读写XML详解
JAVA |日常开发中读写XML详解 前言一、XML 简介二、在 Java 中读取 XML2.1 使用 DOM(Document Object Model)方式读取 XML2.2 使用 SAX(Simple API for XML)方式读取 XML 三、在 Java 中写入 XML3.1 使用 DOM 方式写入…...

React 路由与组件通信:如何实现路由参数、查询参数、state和上下文的使用
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

帮我写一篇关于AI搜索网页上编写的文章是否存在版权问题的文章, 字数在 3000 字左右。文心一言提问, 记录后用.
AI搜索网页上编写的文章是否存在版权问题? 在当今科技飞速发展的时代,AI搜索工具如雨后春笋般涌现,为人们获取信息提供了极大的便利。然而,随之而来的问题是,AI搜索案例中常常出现很多内容缺乏依据,这引发…...

电脑关机的趣味小游戏——system函数、strcmp函数、goto语句的使用
文章目录 前言一. system函数1.1 system函数清理屏幕1.2 system函数暂停运行1.3 system函数电脑关机、重启 二、strcmp函数三、goto语句四、电脑关机小游戏4.1. 程序要求4.2. 游戏代码 总结 前言 今天我们写一点稍微有趣的代码,比如写一个小程序使电脑关机…...

AttributeError: ‘DataFrame‘ object has no attribute ‘append‘的参考解决方法
文章目录 写在前面一、问题描述二、解决方法参考链接 写在前面 自己的测试环境: Ubuntu20.04 一、问题描述 运行开源的python代码的时候,遇到如下问题 AttributeError: DataFrame object has no attribute append二、解决方法 报错中的DataFrame是在…...

java垃圾回收机制介绍
Java垃圾回收机制(Garbage Collection, GC)是Java编程语言中的一项重要特性,它自动管理内存,释放不再使用的对象 1. 堆(Heap): • Java虚拟机(JVM)中用于存储对象实例的内…...

SpringMVC跨域问题解决方案
当Web应用程序尝试从一个源(例如 http://localhost:9090)向另一个不同的源(例如 http://localhost:8080)发起请求时,发现报错: 报错原因:请求被CORS策略拦截了 跨域问题概述 当Web应用程序尝试…...
【语音识别】Zipformer
Zipformer 是kaldi 团队于2024研发的序列建模模型。相比较于 Conformer、Squeezeformer、E-Branchformer等主流 ASR 模型,Zipformer 具有效果更好、计算更快、更省内存等优点。并在 LibriSpeech、Aishell-1 和 WenetSpeech 等常用数据集上取得了当时最好的 ASR 结果…...

vue+uniapp+echarts的使用(H5环境下echarts)
1.安装 npm install echarts4.9.0 --save // 带版本号 2.main.js中全局引用 // import echarts from echarts // 如果是5.0以上版本用这个 import * as echarts from echarts Vue.prototype.$echartsecharts 3.使用 <template><view id"box" style"w…...

【Python网络爬虫笔记】7-网络爬虫的搜索工具re模块
目录 一、网络爬虫中的正则表达式和re模块(一)数据提取的精确性(二)处理复杂的文本结构(三)提高数据处理效率 二、正则表达式的内涵(一)、常用元字符(二)、量…...

为什么选择 React Native 作为跨端方案
为什么选择 React Native 作为跨端方案 我深刻地知道,没有完美的跨端技术,只有适合的场景。脱离适用场景去谈跨端技术没有什么意义。 适用场景 1. 业务更新迭代较快的团队与出海团队 React Native 特别适合那些业务更新频繁、需要快速响应市场的团队…...

服务器与普通电脑有什么区别?
服务器和普通电脑(通常指的是个人计算机,即PC)有众多相似之处,主要构成包含:CPU,内存,芯片,I/O总线设备,电源,机箱及操作系统软件等,鉴于使用要求…...

Oracle 12c Data Guard 环境中的 GAP 修复方法
概述 上文中提到Oracle 12c 引入了多项新技术来简化 Data Guard 环境中的 GAP 修复过程,如(RECOVER … FROM SERVICE)。这些新特性不仅减少了操作步骤,还提高了效率和准确性。本文档将详细说明如何利用这些新特性进行 GAP 修复。…...

力扣 三角dp
动态规划基础题,当前所在元素来自上一行的两列的值。 题目 从图可以看出,每一行的第一个数与最后一个数都是1,然后中间的数是来自它左上方和右上方的数的和。当然并不是要打印这个三角形的形状,因此可以想到正常的打印方式应该是…...

SQL基础语法全解析(上篇)
一、基本概念 1. 数据库术语 数据库(database) - 保存有组织的数据的容器(通常是一个文件或一组文件)。数据表(table) - 某种特定类型数据的结构化清单。模式(schema) - 关于数据库…...

【笔记】Linux服务器端使用百度网盘
1、在python环境下,下载bypy pip install bypy 2、第一次连接需要认证 bypy info 认证通过后百度网盘会出现bypy文件夹,如下 3、查看当前文件夹下的文件 bypy list 若有很多文件夹,可在后面增加文件夹名称,列出对应位置下的文件&a…...

UEFI Spec 学习笔记---3 - Boot Manager(3)
3.2 Boot Manager Policy Protocol EFI_BOOT_MANAGER_POLICY_PROTOCOL----EFI应用程序使用该协议请求UEFI引导管理器使用平台策略连接设备。 typedef struct _EFI_BOOT_MANAGER_POLICY_PROTOCOL EFI_BOOT_MANAGER_POLICY_PROTOCOL; struct _EFI_BOOT_MANAGER_POLICY_PROTOCOL…...

ATTCK红队评估实战靶场(四)
靶机链接:http://vulnstack.qiyuanxuetang.net/vuln/detail/6/ 环境搭建 新建两张仅主机网卡,一张192.168.183.0网段(内网网卡),一张192.168.157.0网段(模拟外网网段),然后按照拓补…...

Android Studio 历史版本下载
Android Studio 历史版本下载 官方链接:https://developer.android.google.cn/studio/archive 通过gradle插件版本反查Android Studio历史版本 Android Studio Ladybug | 2024.2.1 October 1, 2024 【https://redirector.gvt1.com/edgedl/android/studio/ide-zip…...

微信小程序px和rpx单位互转方法
js代码如下 Page({data: {width: 0,width2: 0},onLoad: function (options) {let px this.pxToRpx(380)let rpx this.rpxToPx(730.7692307692307) // 检查两个互转是否是相同即可,例如pxToRpx(380)转成730.7692307692307 则rpxToPx(730.7692307692307)如果是380则代表互转没…...

Vercel 部署与管理指南:简化前端应用的自动化部署流程
引言 在现代的前端开发中,部署和托管项目一直是开发者关注的重要环节。Vercel,作为一个专注于简化前端开发和部署的平台,凭借其强大的自动化功能、全球内容分发网络(CDN)以及对 Next.js 等框架的优越支持,…...

Java11使用JVM同一日志框架启用日志记录
你可以使用-Xlog选项配置或启用Java虚拟机同一日志框架的日志记录。 -Xlog:gc*trace:file/Users/xx/gc-%t.log:time,tags,level,pid,tid,hostname,path:filecount3,filesize10K -Xlog:gc*trace:stdout:time,tags,level,pid,tid,hostname:filecount3,filesize10K -Xlog:gc*trac…...

onlyoffice实现文档比对(Beta版)-纯文字比对(非OCR)
一、说明 文档比对光靠前端或者后端是无法实现的。 该文中的实现方案为:onlyofficejava。java进行文档差异化比较并输出对比结果,only进行得到结果处理渲染。 此方案目前为Beta版本,简单Word Demo实现了比对结果。css、关联动态效果登将在后期…...

JS querySelector方法的优点
1. 灵活性 支持所有 CSS 选择器 ID 选择器:#id 示例:document.querySelector(#myId)解释:选择 id 为 myId 的元素。类选择器:.class 示例:document.querySelector(.myClass)解释:选择具有 class 为 myCla…...

利用获取商品详情API:item_get可以获取到淘宝商品详情的哪些数据?
先来看下测试的返回数据吧 items: { total_results: 76, totalpage: 8, page_size: 10, page: "1", item: [ { rate_content: "和我家的鞋柜特别搭,加上这一条遮挡布,感觉整洁多了,布料不是硬邦邦的那种,很满意。…...

【大数据学习 | 面经】Spark 3.x 中的AQE(自适应查询执行)
Spark 3.x 中的自适应查询执行(Adaptive Query Execution,简称 AQE)通过多种方式提升性能,主要包括以下几个方面: 动态合并 Shuffle 分区(Coalescing Post Shuffle Partitions): 当 …...

[Vue]Vue-router
路由 对前端路由的理解 在前端技术早期,一个 url 对应一个页面,如果要从 A 页面切换到 B 页面,那么必然伴随着页面的刷新。这个体验并不好,不过在最初也是无奈之举——用户只有在刷新页面的情况下,才可以重新去请求数…...

【HarmonyOS】鸿蒙应用使用lottie动画
【HarmonyOS】鸿蒙应用使用lottie动画 一、lottie动画是什么? https://airbnb.design/lottie Lottie是由Airbnb团队开发的一个适用于iOS、Android、React Native、Web和Windows的开源动画库,用于解析使用Bodymovin导出为JSON的Adobe After Effects动…...