问题代码:

 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也无法得到执行

解决方案:

  1. 不应该在回调中调用DeleteTimerQueueTimer中止线程
  2. 如果必须在回调中中止线程,CompletionEvent应设为NULL,标记当前线程结束后,直接返回0(执行失败),回调执行完,不再继续执行
  3. CreateTimerQueueTimer使用Flag WT_EXECUTEDEFAULT开启新线程,即使上一个timer线程死锁,第二个线程仍可以执行

翻译

搜索

复制

Windows线程API —CreateTimerQueueTimer/DeleteTimerQueueTimer的使用的更多相关文章

  1. 第11章 Windows线程池(2)_Win2008及以上的新线程池

    11.2 Win2008以上的新线程池 (1)传统线程池的优缺点: ①传统Windows线程池调用简单,使用方便(有时只需调用一个API即可) ②这种简单也带来负面问题,如接口过于简单,无法更多去控制 ...

  2. 第11章 Windows线程池(1)_传统的Windows线程池

    第11章 Windows线程池 11.1 传统的Windows线程池及API (1)线程池中的几种底层线程 ①可变数量的长任务线程:WT_EXECUTELONGFUNCTION ②Timer线程:调用 ...

  3. mfc 调用Windows的API函数实现同步异步串口通信(源码)

    在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信.串口通信方便易行,应用广泛. 一般情况下,工控机和各智能仪表通过RS485总线进行通信.RS485的通信方式是半 ...

  4. windows线程池四种情形(win核心读书笔记)

    windows线程池四种情形(win核心读书笔记) Mircosoft从Windows2000引入线程池API,并在Vista后对线程池重新构架,引入新的线程池API.以下所有线程池函数均适用于Vis ...

  5. Windows录音API学习笔记(转)

    源:Windows录音API学习笔记 Windows录音API学习笔记 结构体和函数信息  结构体 WAVEINCAPS 该结构描述了一个波形音频输入设备的能力. typedef struct { W ...

  6. windows内核Api的学习

    windows内核api就是ntoskrnl.exe导出的函数.我们能够跟调用应用层的api一样,调用内核api. 只是内核api须要注意的是.假设函数导出了.而且函数文档化(也就是能够直接在msdn ...

  7. c运行时库,c标准库,Windows系统api的关系

    原文地址:http://blog.csdn.net/seastars_sh/article/details/8233324 C运行库和C标准库的关系 C标准库,顾名思义既然是标准,就是由标准组织制定的 ...

  8. Windows录音API学习笔记

    Windows录音API学习笔记 结构体和函数信息  结构体 WAVEINCAPS 该结构描述了一个波形音频输入设备的能力. typedef struct { WORD      wMid; 用于波形 ...

  9. Windows Composition API 指南 - 认识 Composition API

    微软在 Windows 10中 面向通用 Windows 应用 (Universal Windows Apps, UWA) 新引入了一套用于用户界面合成的 API:Composition API.Co ...

  10. Windows录音API学习笔记--转

    Windows录音API学习笔记 结构体和函数信息  结构体 WAVEINCAPS 该结构描述了一个波形音频输入设备的能力. typedef struct { WORD      wMid; 用于波形 ...

随机推荐

  1. spring boot整合spring cloud

    本项目还是通过卖票和买票模块来介绍spring cloud. 1.新建服务注册模块:eureka-server 1.1 配置pom <?xml version="1.0" e ...

  2. C++ 多线程的错误和如何避免(4)

    对共享的资源或者数据做加锁处理 在多线程的环境下,有时需要多个线程对同一个资源或者数据进行操作,如果没有加锁,容易出现未定义的行为. 比如: #include <iostream> #in ...

  3. C++ 时间复杂度

    看到网上一些资料的案例不全,所以自己开个来复习. O(1)<O(log2n)<O(n)<O(nlog2n)<O(n^2)<O(n^3)<-<O(2^n)< ...

  4. SBI信息反馈法

    https://baijiahao.baidu.com/s?id=1605128367255769158&wfr=spider&for=pc

  5. ubuntu18.04更换下载源

    步骤一 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 步骤二 vim /etc/apt/sources.list 步骤三 # http ...

  6. c++复习笔记——STL(vector)

    c++-----STL容器系列(1) vector 1 介绍 Vector是stl容器中一种常见的容器 ,基本和数组类似,其大小(size)可变,常用于数组长度不确定时来代替数组,当数据超过vecto ...

  7. SpringCloud 网关组件Gateway

    官网文档: https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/ 1. 概述 1.1 什么是网关 ...

  8. Rsync 备份服务搭建

    Rsync 备份服务搭建 目录 Rsync 备份服务搭建 一. 前言 二. rsync 和 sersync 2.1 rsync 基本语法 2.2 本地文件传输 2.3 ssh 远程文件传输 2.4 基 ...

  9. 替换掉Chrome浏览器的新标签页【已做好自己的插件,并提供下载】

    https://jingyan.baidu.com/article/fc07f9891b256312ffe5190a.html 我做好了自己的 Chrome 新插件 https://files.cnb ...

  10. max30100心率血氧健康传感器调试总结备忘

    前记  在健康监测领域,心率血氧传感器是一个非常重要的前端采集设备.了解,研究并使用它,是一个方案商的基本素质.鉴于此,笔者花了一些时间在不同的硬件平台来使用它.中间遇到了一些问题值得总结和反思一下. ...