You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将用户态24小时倒计时线程迁移至内核态后台运行?

将用户态24小时倒计时迁移至内核空间的实现方案

原始用户态代码

用户提供的用户态倒计时实现代码如下:

const int SECONDS_IN_24_HOURS = 24 * 60 * 60;

DWORD WINAPI TimerThreadFunction(LPVOID lpParam)
{
    for (int i = 0; i < SECONDS_IN_24_HOURS; ++i)
    {
        double currentTime = MyTimer(); 
        std::cout << "Thread " << GetCurrentThreadId() << " countdown at: " << i + 1 << " seconds, Current time: " << currentTime << " seconds\n";
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    std::cout << "---------------- 24 hours have passed! ----------------\n";
    return 0;
}

int main()
{
    HANDLE hThread;
    DWORD dwThreadId;

    // Create a thread to run the timer function
    hThread = CreateThread(
        NULL,                   // default security attributes
        0,                      // default stack size
        TimerThreadFunction,    // thread function
        NULL,                   // parameter to thread function
        0,                      // default creation flags
        &dwThreadId             // returns the thread identifier
    );

    if (hThread == NULL)
    {
        return 1;
    }

    std::cout << "Thread created successfully with ID: " << dwThreadId << std::endl;

    SetThreadAffinityMask(hThread, 1 << 0);

    WaitForSingleObject(hThread, INFINITE);

    CloseHandle(hThread);

    return 0;
}

内核态实现思路与代码

内核空间无法直接使用用户态API(如CreateThread、std::cout),必须替换为内核专属机制,以下是两种可行实现方案:

方案1:系统线程+逐秒休眠(与用户态逻辑对齐)

通过创建内核系统线程,配合KeDelayExecutionThread实现逐秒倒计时,适合需要实时输出进度的场景:

#include <ntddk.h>

#define SECONDS_IN_24_HOURS (24 * 60 * 60)

// 内核系统线程函数
VOID TimerSystemThread(PVOID Context)
{
    UNREFERENCED_PARAMETER(Context);
    HANDLE threadHandle = NULL;
    NTSTATUS status = PsGetCurrentThread(&threadHandle);

    // 设置线程亲和性到CPU 0
    KAFFINITY affinityMask = 1 << 0;
    status = KeSetSystemThreadAffinityEx(threadHandle, affinityMask);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("Failed to set thread affinity: 0x%X\n", status);
    }

    // 24小时倒计时循环
    for (ULONG i = 0; i < SECONDS_IN_24_HOURS; ++i)
    {
        // 获取当前系统时间(转换为秒)
        LARGE_INTEGER currentTime;
        KeQuerySystemTime(&currentTime);
        double seconds = (double)currentTime.QuadPart / 10000000.0;

        // 输出到调试器
        DbgPrint("Kernel Thread %lu countdown at: %lu seconds, Current time: %.2f seconds\n",
                 PsGetCurrentThreadId(), i + 1, seconds);

        // 休眠1秒(负数值表示相对时间,1秒=10^7个100纳秒单位)
        LARGE_INTEGER delay;
        delay.QuadPart = -10000000LL;
        KeDelayExecutionThread(KernelMode, FALSE, &delay);
    }

    DbgPrint("---------------- 24 hours have passed! ----------------\n");

    // 终止内核线程
    PsTerminateSystemThread(STATUS_SUCCESS);
}

// 驱动入口函数
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    UNREFERENCED_PARAMETER(RegistryPath);
    HANDLE threadHandle = NULL;
    NTSTATUS status;

    // 创建系统线程
    status = PsCreateSystemThread(
        &threadHandle,
        THREAD_ALL_ACCESS,
        NULL,
        NULL,
        NULL,
        TimerSystemThread,
        NULL
    );

    if (!NT_SUCCESS(status))
    {
        DbgPrint("Failed to create system thread: 0x%X\n", status);
        return status;
    }

    DbgPrint("Kernel thread created successfully with ID: %lu\n", PsGetCurrentThreadId());

    // 关闭线程句柄(内核线程会独立运行)
    ZwClose(threadHandle);

    // 设置驱动卸载回调
    DriverObject->DriverUnload = [](PDRIVER_OBJECT DriverObject) {
        UNREFERENCED_PARAMETER(DriverObject);
        DbgPrint("Timer driver unloaded\n");
    };

    return STATUS_SUCCESS;
}

方案2:KTIMER+DPC(高效长定时)

如果不需要逐秒输出进度,使用内核定时器KTIMER结合延迟过程调用DPC更节省系统资源,无需持续占用线程:

#include <ntddk.h>

#define SECONDS_IN_24_HOURS (24 * 60 * 60)

KTIMER g_countdownTimer;
KDPC g_countdownDpc;

// DPC回调函数:定时结束时执行
VOID CountdownDpcRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
{
    UNREFERENCED_PARAMETER(Dpc);
    UNREFERENCED_PARAMETER(DeferredContext);
    UNREFERENCED_PARAMETER(SystemArgument1);
    UNREFERENCED_PARAMETER(SystemArgument2);

    DbgPrint("---------------- 24 hours have passed! ----------------\n");
}

// 驱动入口函数
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    UNREFERENCED_PARAMETER(RegistryPath);
    
    // 初始化定时器和DPC
    KeInitializeTimer(&g_countdownTimer);
    KeInitializeDpc(&g_countdownDpc, CountdownDpcRoutine, NULL);

    // 设置24小时后触发定时器
    LARGE_INTEGER delay;
    delay.QuadPart = -SECONDS_IN_24_HOURS * 10000000LL; // 负数值表示相对时间
    KeSetTimerEx(&g_countdownTimer, delay, 0, &g_countdownDpc);

    DbgPrint("24-hour countdown timer started\n");

    // 设置驱动卸载回调
    DriverObject->DriverUnload = [](PDRIVER_OBJECT DriverObject) {
        UNREFERENCED_PARAMETER(DriverObject);
        // 取消定时器
        KeCancelTimer(&g_countdownTimer);
        DbgPrint("Timer driver unloaded\n");
    };

    return STATUS_SUCCESS;
}

关键注意事项

  • 内核驱动需使用Windows Driver Kit(WDK)编译,测试环境需开启测试签名模式
  • 内核中无控制台输出,DbgPrint的内容需通过WinDbg等调试工具查看
  • 内核线程禁止调用用户态C++标准库,必须使用内核原生API
  • 驱动卸载时需清理定时器或线程资源,避免内存泄漏或系统不稳定

内容的提问来源于stack exchange,提问作者eden sson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 14:56:22