工作线程快速优雅退出方式探讨
本文我们不用定时器。定时器会阻塞消息循环。先看需求:
我们先看第一种,有一个任务,要求每1秒钟执行一次,最常见的写法如下两种
bool bExitThread = false;
DWORD WorkThread1(LPVOID param)
{while (false == bExitThread){//// to-do 这里是执行任务的具体代码//Sleep(1000);}return 0;
}
或者如下:
HANDLE hEventExit = ::CreateEvent(NULL, FALSE, FALSE, _T("hEventExit"));DWORD WorkThread1(LPVOID param)
{while (false == bExitThread){DWORD nRet = ::WaitForSingleObject(hEventExit, 1000);if (WAIT_TIMEOUT != nRet){break;}////to-do 执行任务具体代码//}return 0;
}
勉强可以用了,但是有明显缺点,是当软件要退出时,必须等待该线程1秒钟,非常不实时。无法完成快速响应退出。很致命啊。
于是有了改进的写法,如下两种:
DWORD WorkThread2(LPVOID param)
{while (false == bExitThread){//// to-do 这里是具体代码//for (int i = 0; i < 100; i++){Sleep(10);if (bExitThread)break;}}return 0;
}
或者如下:
HANDLE hEventExit = ::CreateEvent(NULL, FALSE, FALSE, _T("hEventExit"));DWORD WorkThread1(LPVOID param)
{DWORD nCount = 0;while (false == bExitThread){DWORD nRet = ::WaitForSingleObject(hEventExit, 10);if (WAIT_TIMEOUT != nRet){break;}nCount++;if (0 == nCount % 100){////to-do 执行任务具体代码//}}return 0;
}
不得不说,这两种改进方式,的确做到了1秒钟执行1次任务,也能做到当软件退出时,能极快速的退出该线程。不得不说这种化整为零的好方式,比前面第一种好了许多,甚至你可以直接把睡眠或等待改成1毫秒,就可以达到更低时延的快速退出线程。
但是,假如需求做一下调整,但有多个任务,比如3个任务需要执行,而且,
任务1,必须保证每1秒钟要执行一次(耗时忽略不计)
任务2,必须保证每2秒钟要执行一次(耗时忽略不计)
任务3,必须保证每3秒钟要执行一次(耗时忽略不计)
(不准使用定时器N个定时器,定时器会导致一顿一顿的,也不准开N个定时器再在里面各开1个线程), 我们怎么做到保证N个任务,按如上要求执行,还要能保证退出时,线程能最快的退出。
事实上这才是我们现实需求中最最常见的。这个时候,同样也可以用化整为零的多次Sleep或WaitForSingleObject来完成。比如如下,巧用nCount计数来完成:
HANDLE hEventExit = ::CreateEvent(NULL, FALSE, FALSE, _T("hEventExit"));DWORD WorkThread3(LPVOID param)
{bool bSet = false;DWORD nCount = 0;while (false == bExitThread){DWORD nRet = ::WaitForSingleObject(hEventExit, 1);if (WAIT_TIMEOUT != nRet){break;}nCount++;if (0 == nCount % 1000){//// to-do Task1//}if (0 == nCount % 2000){//// to-do Task2//}if (0 == nCount % 3000){//// to-do Task3//}}return 0;
}
显然是达到了多个任务都可以按照指定的时间间隔频次执行,而且还能做到软件退出时,该线程也能快速的退出。
但假如需求再变一下,只准开一个线程,3个任务需求同上,但是每个任务执行耗时不可忽略,任务执行耗时1秒却不可中断。这个时候,我们如何做到软件退出时,最快的退出呢?
显然软件正好退出时,可能该线程刚好进入任务N执行,执行1秒耗时不可中断,必然需要等待。
显然这个时候需要做到快速优雅的退出,就比较困难了。如果实在不想等待1秒的话,我们可以直接PauseThread或TerminateThread,来暂停或打断该线程的执行,然后退出软件。这也不失是一种快速响应退出线程的好方法了。
虽然可以做到快速退出了,但是有一个需求是没有满足的,那就是:
- 每隔1秒执行一次Task1;
- 每隔2秒执行一次Task2;
- 每隔3秒执行一次Task3;
为什么呢,因为这种方式有个弊端,当第2秒时,Task1执行耗时1秒,它占了1秒,导致了Task2往后延了1秒执行;当第3秒时,Task2,Task3依次又顺延了许多秒,并没有达到需求。所以这个时候只准开1个线程,就很难实时满足需求了。只能改成开3个线程单独去处理了。
搁笔。如有疑问,站内信联系
相关文章:
工作线程快速优雅退出方式探讨
本文我们不用定时器。定时器会阻塞消息循环。先看需求: 我们先看第一种,有一个任务,要求每1秒钟执行一次,最常见的写法如下两种 bool bExitThread false; DWORD WorkThread1(LPVOID param) {while (false bExitThread){//// to…...
甘特图控件DHTMLX Gantt教程:用PHP:Laravel实现Gantt(上)
DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的大部分开发需求,具备完善的甘特图图表库,功能强大,价格便宜,提供丰富而灵活的JavaScript API接口,与各种服务器端技术&am…...
ffmpeg-命令大全03
ffplay/mpv 查看所有的解码器 ffplay -decoders >>decoders.txt ffplay无延时无缓存播放 ffplay -fflags nobuffer -i "%1" ffplay指定size播放 ffplay -x 480 -y 270 -i "%1" ffplay指定解码器 ffplay -vcodec hevc_cuvid "%1" […...
MATLAB中太赫兹时域光谱的最大似然参数估计
目录 一、引言 二、最大似然估计的基本原理 三、MATLAB中的最大似然估计实现 四、太赫兹时域光谱的最大似然参数估计 五、结论 六、参考文献 一、引言 太赫兹波(Terahertz wave)是电磁谱中介于微波与光波之间的一段频率范围,频率大约在…...
详解MySQL的并发控制
目录 1.概述 2.事务 2.1.什么是事务 2.2.事务的隔离级别 2.2.1.三种数据一致性问题 2.2.2.四种隔离级别 2.3.如何设置隔离级别 3.锁 3.1.锁与事务的关系 3.2.分类 3.3.表锁 3.3.1.概述 3.3.2.读锁 3.3.3.写锁 3.3.4.保护机制 3.4.行锁 3.4.1.概述 3.4.2.什么…...
Android Termux安装MySQL数据库 | 公网安全远程连接【cpolar内网穿透】
文章目录 前言1.安装MariaDB2.安装cpolar内网穿透工具3. 创建安全隧道映射mysql4. 公网远程连接5. 固定远程连接地址 前言 Android作为移动设备,尽管最初并非设计为服务器,但是随着技术的进步我们可以将Android配置为生产力工具,变成一个随身…...
SpringBoot的常见配置
SpringBoot基础配置 1. 配置文件格式问题导入1.1 修改服务器端口1.2 自动提示功能消失解决方案1.3 SpringBoot配置文件加载顺序 2. yaml问题导入2.1 yaml语法规则2.2 yaml数组数据2.3 yaml数据读取 3. 多环境开发配置问题导入3.1 多环境启动配置3.2 多环境启动命令格式3.3 多环…...
LabVIEWCompactRIO 开发指南25 实施LabVIEW FPGA代码的方法
LabVIEWCompactRIO 开发指南25 实施LabVIEW FPGA代码的方法 开始开发时,应在LabVIEW项目的FPGA目标下创建VI,以便使用LabVIEW FPGA选板进行编程,该选板是LabVIEW选板的子集,包括一些LabVIEW FPGA特定函数。 应该在仿真模式下开…...
如何利用Jmeter从0到1做一次完整的压测
压测,在很多项目中都有应用,是测试小伙伴必备的一项基本技能,刚好最近接手了一个小游戏的压测任务,一轮压测下来,颇有收获,赶紧记录下来,与大家分享一下,希望大家能少踩坑。 一、压测…...
蓝桥:前端开发笔面必刷题——Day1 数组(一)
文章目录 📋前言🎯数组中重复的数字📚题目内容✅解答 🎯两数之和📚题目内容✅解答 🎯替换空格📚题目内容✅解答 🎯二维数组中的查找📚题目内容✅解答 📝最后 …...
SQL 教程-入门基础篇
文章目录 SQL 简介SQL 语法SQL SELECT 语句SQL SELECT DISTINCT 语句SQL WHERE 子句SQL AND & OR 运算符SQL ORDER BY 关键字SQL INSERT INTO 语句SQL UPDATE 语句SQL DELETE 语句 SQL 简介 SQL(Structured Query Language)是一种用于管理和操作关系…...
循环自相关函数和谱相关密度(六)——信号的循环平稳性(循环自相关函数)原理及推导
在通信、遥测、雷达和声纳系统中,一些人工信号是一类特殊的非平稳信号,它们的非平稳性表现为周期平稳性。通信信号常用待传输信号对周期性信号的某个参数进行调制、如对正弦载波进行调幅、调频和调相,以及对周期性脉冲信号进行脉幅、脉宽和脉位调制,都会产生具有周期平稳性…...
C/C++:04. 多态和虚函数
不加virtual,只能访问成员变量,不能访问成员函数 文章目录 前言1 虚函数与多态不用虚函数的多态使用虚函数的多态 2 C虚函数注意事项 构成多态的条件C虚函数注意事项构成多态的条件什么时候声明虚函数 3 C虚析构函数的必要性总结 前言 本节阐述C中的多态…...
拿下多个定点/比亚迪要上!这项技术要「降维打击」单目感知
2008年,斯巴鲁在全球首次推出了搭载有立体视觉摄像头的主动安全解决方案,并具有紧急制动功能的“EyeSight”。2010年,斯巴鲁推出升级版的“EyeSight”,成为世界上首个可以在全车速范围内避免碰撞的量产技术系统。 2014年ÿ…...
Go 的时间操作
Go 的时间操作 1. time 包 1.1. 时间类型 Go 语言中时间类型有两种: time.Time:表示时间的类型,常见的有两种方式: time.Now():获取当前的时间time.Date():根据指定的年、月、日、时、分、秒、纳秒等创…...
ThreeJS进阶之矩阵变换
ThreeJS的矩阵变换 Three.js使用matrix编码3D变换 —— 平移(位置),旋转和缩放。Object3D的每个实例都有一个matrix,用于存储该对象的位置,旋转和比例。这里介绍如何更新对象的变换。 三维物体(Object3D) 这是Three.js中大部分对象的基类,提供了一系列的属性和方法来对…...
分布式锁概念
什么是分布式锁 方案一:SETNX EXPIRE 方案二:SETNX value值是(系统时间过期时间) 方案三:使用Lua脚本(包含SETNX EXPIRE两条指令) 方案四:SET的扩展命令(SET EX PX NX) 方案五…...
PMP课堂模拟题目及解析(第10期)
91. 在项目执行阶段,一名项目干系人要求项目经理加入一个新过程的优化。项目经理应该怎么做? A. 执行实施整体变更控制过程。 B. 与过程专家一起审查项目。 C. 将优化项目分配给团队。 D. 拒绝范围蔓延企图。 92. 项目经理要求团队提供对项目应急计…...
Arm微架构分析系列3——Arm的X计划
1. 引言 前文介绍了Arm公司近几年在移动处理器市场推出的Cortex-A系列处理器。Cortex-A系列处理器每年迭代,性能和能效不断提升,是一款非常成功的产品。但是,Arm并不满足于Cortex-A系列每年的架构小幅度升级,又推出了X计划&#x…...
Kubernetes(K8S)的基础概念
文章目录 一、Kubernetes介绍1、什么是Kubernetes?2、为什么要用K8S?3、k8s的特性 二、k8s集群架构与组件1、Master组件2、配置存储中心——etcd3、Worker Node 组件 三、k8s核心概念●Pod●Pod 控制器(五大控制器)●Label●Label选择器(Label selector )●Service…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
