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; 用于波形 ...
随机推荐
- Java集合框架学习(八) HashMap详解
HashMap介绍 HashMap是一个基于Map的集合类,用于存储Key和Value的键值对. 通常用HashMap<Key, Value> or HashMap<K, V> ...
- win32 - 按文件的创建日期排序
因项目中使用文件的创建日期来命名文件,所以不用额外查找文件的创建日期再进行排序,记录一下 bool AscendingSortByCreationTime(const std::wstring& ...
- django学习第十一天---django操作cookie和session
Cookie cookie解析 会话 http协议是无状态的,无连接的 导致每次客户端访问服务端需要登录成功之后才能访问的页面,都需要用户再重新登录一遍,用户体验极差. 客户端想了个办法,cookie ...
- ProtoBuffer-nanopb介绍
目录 一.需求 二.环境 三.相关概念 3.1 protocol buffer介绍 3.2 nanopb(支持C语言) 3.3 proto文件 四.proto基本语法 4.1 proto文件的定义 4 ...
- 有了这份Java面试中的葵花宝典,让你面试起飞!!!
HashMap面试题 HashMap与HashTable的区别 1.HashMap线程不安全 HashTable 线程是安全的采用synchronized 2.HashMap允许存放key 为null ...
- 【Azure 存储服务】关于中国区Azure Storage Account 存储账号服务误删除后的恢复问题
问题描述 在Azure上,如果需要恢复之前删除的存储账户(Storage Account), 有什么办法呢? 问题解答 Azure 现在推出了自主恢复已删除的存储账号的功能,具体步骤如下: 第一步: ...
- 【Azure API 管理】APIM中的Policy是否有调用速率的方法(熔断机制)
问题描述 APIM中的Policy是否有调用速率的方法(熔断机制) 问题解答 APIM的限制速率的方式有以下方式: 检查 HTTP 标头 - 强制 HTTP 标头必须存在和/或强制采用 HTTP 标头 ...
- 【Azure Developer】使用 Azure Python 查看 Azure 所有的 Alert rule
问题描述 在Azure Alert 门户中,可以列举出所有Azure资源的Alert rule信息,如下图: 如果像通过Python SDK来获取所有的Alert Rule,有什么可以参考的代码吗? ...
- 【Azure 事件中心】 Event Grid(事件网格)+Azure Functions处理IOT Hub中的消息
问题描述 使用IOT Hub的Events功能,使用Event Grid(事件网格)订阅IOTHub状态消息,发送到Azure Functions.那如何来创建Event Grid触发的Functio ...
- 答对这 9 题你就超越了 83.3% 的图数据库 NebulaGraph 用户
熟悉 NebulaGraph 社区的小伙伴可能都知道一个技能认证叫做:NGCP,全称 NebulaGraph Certified Professional.用户在考试认证期间在 1 个小时内回答 10 ...