刘收获

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

可等待定时器(获取系统时间)

可等待定时器这种内核对象,它们会在某个指定的时间触发,或每隔一段时间触发一次。它们通常用来在某个时间执行一些操作。

  

0x01 创建一个可等待定时器 CreateWaitableTimer

(在创建的时候,可等待的计时器对象总是处于未触发状态)

HANDLE WINAPI CreateWaitableTimer(

    __in_opt  LPSECURITY_ATTRIBUTES lpTimerAttributes, //安全描述符,为NULL时使用默认的

    __in      BOOL bManualReset, //要创建一个手动重置定时器还是一个自动重置计时器

                   //当手动重置计时器被触发时,正在等待该计时器的所有线程都会变成可调度状态

                   //当自动重置计时器被触发时,只有一个正在等待该计时的线程会变成可调度状态

    __in_opt  LPCTSTR lpTimerName //该可等待计时器的名称

);

 

0x02 获取一个已经存在的可等待计时器的句柄 OpenWaitableTimer

 

HANDLE WINAPI OpenWaitableTimer(

    __in  DWORD dwDesiredAccess, //访问权限

    __in  BOOL bInheritHandle, //是否允许子进程继承该句柄

    __in  LPCTSTR lpTimerName //要打开的对象名称

);

 

0x03 触发计时器 SetWaitableTimer函数

 

BOOL WINAPI SetWaitableTimer(

    __in      HANDLE hTimer, //想要触发的计时器

    __in      const LARGE_INTEGER *pDueTime, //计时器第一次触发的时间

    __in      LONG lPeriod, //第一次触发后,计时器的触发频度,当给lPeriod参数传0时,我们设置的是一次性定时器,这种定时器只触发一次,之后再不触发。

    __in_opt  PTIMERAPCROUTINE pfnCompletionRoutine, //异步过程调用APC函数

    __in_opt  LPVOID lpArgToCompletionRoutine, //APC函数的参数

    __in      BOOL fResume //是否继续执行,一般传FALSE

);

 

0x04  将指定的计时器取消 CancelWaitableTimer函数

 

BOOL WINAPI CancelWaitableTimer(

  __in  HANDLE hTimer

);

这样计时器就永远不会触发了,除非以后再调用SetWaitableTimer来对它进行重置。如果想要改变触发器的触发时间,不必先调用CancelWaitableTimer,因为每次调用SetWaitableTimer都会在设置新的触发时间之前将原来的触发时间取消掉。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// 计时器.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <ctime>
using namespace std;
 
 
 
DWORD WINAPI ThreadProcedure(LPVOID ParameterData);
void GetSystemTime();
BOOL __IsLoop = TRUE;
int main()
{
    HANDLE ThreadHandle = CreateThread(NULL, 0,
        (LPTHREAD_START_ROUTINE)ThreadProcedure, NULL, 0, NULL);
    printf("Input AnyKey To Exit\r\n");
    getchar();
 
    __IsLoop = FALSE;
     
    WaitForSingleObject(ThreadHandle, INFINITE);
     
    if (ThreadHandle!=NULL)
    {
        CloseHandle(ThreadHandle);
        ThreadHandle = NULL;
    }
 
    return 0;
}
DWORD WINAPI ThreadProcedure(LPVOID ParameterData)
{
    //创建一个时钟
    HANDLE TimeHandle = NULL;
    LARGE_INTEGER DueTime;
    DueTime.QuadPart = -10000000;
    TimeHandle = CreateWaitableTimer(NULL, FALSE, NULL);
    //同步事件(SynchronizationEvent)
    //当事件对象为激发时,如遇到KeWaitForXX等内核函数,事件对象则自动变回未激发态
    //通知事件(NotificationEvent)
    //当事件对象为激发时,如遇到KeWaitForXX等内核函数,事件对象则不会变回未激发态
    //If this parameter is TRUE, the timer is a manual-reset notification timer. Otherwise, the timer is a synchronization timer.
    while (__IsLoop)
    {
        if (!SetWaitableTimer(TimeHandle, &DueTime,
            0, NULL, NULL, 0))
        {
            printf("SetWaitableTimer failed (%d)\n", GetLastError());
            return 0;
        }
        BOOL IsOk = WaitForSingleObject(TimeHandle, INFINITE);
        IsOk -= WAIT_OBJECT_0;
        if (IsOk==0)
        {
            system("cls");     
            GetSystemTime();
        }
        else
        {
            break;
        }
    }
    CancelWaitableTimer(TimeHandle);
    CloseHandle(TimeHandle);
    TimeHandle = NULL;
    printf("ThreadProcedure() Exit\r\n");
    return 0;
}
void GetSystemTime()
{
    char TimeData[MAX_PATH] = { 0 };
    auto TimeObject = time(NULL);
    tm v1;
    localtime_s(&v1, &TimeObject);
    //格式化时间字符串
    strftime(TimeData, _countof(TimeData), "%Y-%m-%d %H:%M:%S", &v1);
    printf("%s\r\n", TimeData);
}

  

posted on   沉疴  阅读(615)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示