Windows线程API —CreateTimerQueueTimer/DeleteTimerQueueTimer的使用
问题代码:
1 #include<windows.h>
2 #include<iostream>
3 #include<thread>
4 HANDLE h1;
5 HANDLE h2;
6
7 void CALLBACK test(PVOID a, BOOLEAN b)
8 {
9 std::cout << "This a test function excuted by Thread:" << std::this_thread::get_id()<< std::endl;
10 //std::cout << "Here we try to delete timer in Thread:" << std::this_thread::get_id() << std::endl;
11 if (0 == DeleteTimerQueueTimer(NULL, h1, INVALID_HANDLE_VALUE))
12 {
13 std::cout << "Timer Deleted Failed in Thread:" << std::this_thread::get_id() << std::endl;
14 }
15 std::cout << "Timer Deleted Successfully in Thread:" << std::this_thread::get_id() << std::endl;
16
17 }
18 void CALLBACK test1(PVOID l, BOOLEAN t)
19 {
20 std::cout << "This a test1 function excuted by Thread:" << std::this_thread::get_id() << std::endl;
21 }
22
23 int main()
24 {
25
26 std::cout << "******This is a Test for TimeQueueTimer in Windows API******" << std::endl;
27 std::cout << "Main thread is executed by thread: " << std::this_thread::get_id() << std::endl;
28 //test(PVOID(1), TRUE);
29 try
30 {
31 CreateTimerQueueTimer(&h1, NULL, WAITORTIMERCALLBACK(test), NULL, 0, 1000, WT_EXECUTEINTIMERTHREAD);
32 //Sleep(1000);
33
34 CreateTimerQueueTimer(&h2, NULL, WAITORTIMERCALLBACK(test1), NULL, 0, 1000, WT_EXECUTEINTIMERTHREAD);
35
36
37 //CreateTimerQueueTimer(&h1, NULL, [](PVOID lpParameter, BOOLEAN TimerOrWaitFired) {
38 // test(lpParameter, TimerOrWaitFired); // Call your original test function from within the lambda
39 // }, NULL, 0, 1000, WT_EXECUTEINTIMERTHREAD);
40
41 }
42 catch (const std::exception& e)
43 {
44 std::cout << "something error with the timer: " << e.what() << std::endl;
45 }
46
47
48 if (std::cin.get())
49 {
50 if (0 == DeleteTimerQueueTimer(NULL, h2, INVALID_HANDLE_VALUE))
51 {
52 std::cout << "Timer Deleted Failed in Thread:" << std::this_thread::get_id() << std::endl;
53 }
54 std::cout << "Timer Deleted Successfully in Thread:" << std::this_thread::get_id() << std::endl;
55
56 };
57 Sleep(1000);
58
59 return 0;
60 }
Main()函数中test1回调无法执行!
问题分析:
CreateTimerQueueTimer和DeleteTimerQueueTimer 分别负责线程的开启和中止,函数定义如下:
BOOL CreateTimerQueueTimer(
[out] PHANDLE phNewTimer,
[in, optional] HANDLE TimerQueue,
[in] WAITORTIMERCALLBACK Callback,
[in, optional] PVOID Parameter,
[in] DWORD DueTime,
[in] DWORD Period,
[in] ULONG Flags
);
BOOL DeleteTimerQueueTimer(
[in, optional] HANDLE TimerQueue,
[in] HANDLE Timer,
[in, optional] HANDLE CompletionEvent
);
主线程中分别利用CreateTimerQueueTimer开启后台线程调用回调test()和test1(),并在test()调用中结束调用。由于DeleteTimerQueueTimer中CompletionEvent中使用的是INVALID_HANDLE_VALUE,导致线程会等待所有timer线程执行结束,才能返回。而当前执行回调的线程等不到自己结束,陷入死锁。因为CreateTimerQueueTimer的Flag参数使用的是WT_EXECUTEINTIMERTHREAD,导致test1回调和test使用的是同一线程,而test线程已经死锁,所以test1也无法得到执行
解决方案:
- 不应该在回调中调用DeleteTimerQueueTimer中止线程
- 如果必须在回调中中止线程,CompletionEvent应设为NULL,标记当前线程结束后,直接返回0(执行失败),回调执行完,不再继续执行
- CreateTimerQueueTimer使用Flag WT_EXECUTEDEFAULT开启新线程,即使上一个timer线程死锁,第二个线程仍可以执行
翻译
搜索
复制
Windows线程API —CreateTimerQueueTimer/DeleteTimerQueueTimer的使用的更多相关文章
- 第11章 Windows线程池(2)_Win2008及以上的新线程池
11.2 Win2008以上的新线程池 (1)传统线程池的优缺点: ①传统Windows线程池调用简单,使用方便(有时只需调用一个API即可) ②这种简单也带来负面问题,如接口过于简单,无法更多去控制 ...
- 第11章 Windows线程池(1)_传统的Windows线程池
第11章 Windows线程池 11.1 传统的Windows线程池及API (1)线程池中的几种底层线程 ①可变数量的长任务线程:WT_EXECUTELONGFUNCTION ②Timer线程:调用 ...
- mfc 调用Windows的API函数实现同步异步串口通信(源码)
在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信.串口通信方便易行,应用广泛. 一般情况下,工控机和各智能仪表通过RS485总线进行通信.RS485的通信方式是半 ...
- windows线程池四种情形(win核心读书笔记)
windows线程池四种情形(win核心读书笔记) Mircosoft从Windows2000引入线程池API,并在Vista后对线程池重新构架,引入新的线程池API.以下所有线程池函数均适用于Vis ...
- Windows录音API学习笔记(转)
源:Windows录音API学习笔记 Windows录音API学习笔记 结构体和函数信息 结构体 WAVEINCAPS 该结构描述了一个波形音频输入设备的能力. typedef struct { W ...
- windows内核Api的学习
windows内核api就是ntoskrnl.exe导出的函数.我们能够跟调用应用层的api一样,调用内核api. 只是内核api须要注意的是.假设函数导出了.而且函数文档化(也就是能够直接在msdn ...
- c运行时库,c标准库,Windows系统api的关系
原文地址:http://blog.csdn.net/seastars_sh/article/details/8233324 C运行库和C标准库的关系 C标准库,顾名思义既然是标准,就是由标准组织制定的 ...
- Windows录音API学习笔记
Windows录音API学习笔记 结构体和函数信息 结构体 WAVEINCAPS 该结构描述了一个波形音频输入设备的能力. typedef struct { WORD wMid; 用于波形 ...
- Windows Composition API 指南 - 认识 Composition API
微软在 Windows 10中 面向通用 Windows 应用 (Universal Windows Apps, UWA) 新引入了一套用于用户界面合成的 API:Composition API.Co ...
- Windows录音API学习笔记--转
Windows录音API学习笔记 结构体和函数信息 结构体 WAVEINCAPS 该结构描述了一个波形音频输入设备的能力. typedef struct { WORD wMid; 用于波形 ...
随机推荐
- php+bootstrap+jquery+mysql实现购物车项目案例
获取源码 一键三连后,评论区留下邮箱安排发送:) 介绍 使用php,bootstrap,jquery,mysql实现的简易购物车案例. 通过本案例,你将学习到以下知识点: php 操作 mysql 实 ...
- Go 中的反射 reflect 介绍和基本使用
一.什么是反射 在计算机科学中,反射(英语:reflection)是指计算机程序在运行时(runtime)可以访问.检测和修改它本身状态或行为的一种能力.用比喻来说,反射就是程序在运行的时候能够&qu ...
- Docker实践之05-限制Docker容器运行资源
Docker容器在默认情况下会使用宿主机的所有CPU和内存资源,为了明确限制每一个Docker容器的运行资源,需按如下操作进行设置. 首先,执行:sudo docker info,如果提示:" ...
- 硬件开发笔记(十一):Altium Designer软件介绍、安装过程和打开pcb工程测试
前言 前面做高速电路,选择是阿li狗,外围电路由于读者熟悉AD,使用使用ad比较顺手,非高速电路就使用AD了,其实AD也可以做高速电路,由于笔者从13年开始做硬是从AD9开始的,所以开始切入AD做 ...
- 矩池云快速安装torch-sparse、torch-geometric等包
租用机器,按自己需要的环境选择一个环境,我这里选择的是Pytorch 1.10. 租用成功后点击租用页面的 Jupyterlab 链接. Jupyterlab 里新建一个Terminal 用来安装环境 ...
- Xilinx GTH 简介 ,CoaXpress FPGA PHY 部分
什么是GTH GTH 是Xilinx UltraScale系列FPGA上高速收发器的一种类型,本质上和其它名称如GTP, GTX等只是器件类型不同.速率有差异:GTH 最低速率在500Mbps,最高在 ...
- 用BootstrapBlazor制作修改订单字段的页面
1.在Shared文件夹下新增一个razor 2.页面初始化的时候获取订单信息 准备一个名为OrderId的参数 准备重写页面初始化时的方法 改成异步的形式来重写 4.获取数据 就3行代码. 声明这个 ...
- 【Azure 应用服务】调用Azure REST API来获取 App Service的访问限制信息(Access Restrictions)以及修改
问题描述 昨天的博文中(https://www.cnblogs.com/lulight/p/17099179.html)介绍了使用Python SDK 来获取App Service的访问限制信息,那么 ...
- Java Servlet单元测试
Java Servlet单元测试 1. 解决痛点 虽然目前主流的开发方式,很多都是通过controll或者微服务提供api.但是不免还是需要写几个servlet完成接口开发.按照常规,servlet调 ...
- [JS] 获取超星视频题答案
// 解除鼠标限制 var btnn = $(document.getElementById("iframe").contentWindow.document.getElement ...