1. 程式人生 > >Windows核心編程:第11章 Windows線程池

Windows核心編程:第11章 Windows線程池

integer code oid 釋放 入口 thread cor done ram

Github

https://github.com/gongluck/Windows-Core-Program.git

//第11章 Windows線程池.cpp: 定義應用程序的入口點。
//

#include "stdafx.h"
#include "第11章 Windows線程池.h"

VOID NTAPI SimpleCB(
    _Inout_     PTP_CALLBACK_INSTANCE Instance,
    _Inout_opt_ PVOID                 Context
)
{

}

VOID NTAPI WorkCB(
    _Inout_     PTP_CALLBACK_INSTANCE Instance,
    _Inout_opt_ PVOID                 Context,
    _Inout_     PTP_WORK              Work
)
{

}

VOID NTAPI TimerCB(
    _Inout_     PTP_CALLBACK_INSTANCE Instance,
    _Inout_opt_ PVOID                 Context,
    _Inout_     PTP_TIMER             Timer
)
{
    static DWORD i = 0;
    i += 1;
    static LARGE_INTEGER li;
    li.QuadPart = -10000000ll * i;
    static FILETIME duetime = { 0 };
    duetime.dwLowDateTime = li.LowPart;
    duetime.dwHighDateTime = li.HighPart;

    SetThreadpoolTimer(Timer, &duetime, 0, 0); //設置定時器
}

VOID NTAPI WaitCB(
    _Inout_     PTP_CALLBACK_INSTANCE Instance,
    _Inout_opt_ PVOID                 Context,
    _Inout_     PTP_WAIT              Wait,
    _In_        TP_WAIT_RESULT        WaitResult
    )
{
    switch (WaitResult)
    {
    case WAIT_OBJECT_0:
        break;
    case WAIT_TIMEOUT:
        break;
    case WAIT_ABANDONED:
        break;
    default:
        break;
    }
}

VOID WINAPI IoCB(
    _Inout_     PTP_CALLBACK_INSTANCE Instance,
    _Inout_opt_ PVOID                 Context,
    _Inout_opt_ PVOID                 Overlapped,
    _In_        ULONG                 IoResult,
    _In_        ULONG_PTR             NumberOfBytesTransferred,
    _Inout_     PTP_IO                Io
)
{
    switch (IoResult)
    {
    case NO_ERROR:
        break;
    default:
        break;
    }
}

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR    lpCmdLine,
    _In_ int       nCmdShow)
{
    //以異步方式調用函數
    BOOL bres = TrySubmitThreadpoolCallback(SimpleCB, nullptr, nullptr); //將工作項添加到線程池隊列
    PTP_WORK pwork = CreateThreadpoolWork(WorkCB, nullptr, nullptr); //創建一個工作項
    SubmitThreadpoolWork(pwork); //向線程池提交一個請求
    WaitForThreadpoolWorkCallbacks(pwork, FALSE/*是否先嘗試取消提交的工作項*/); //取消工作項或等待完成
    CloseThreadpoolWork(pwork); // 釋放工作項內存
    pwork = nullptr;

    //每隔一段時間調用一個函數
    PTP_TIMER ptimer = CreateThreadpoolTimer(TimerCB, nullptr, nullptr); //創建定時器
    LARGE_INTEGER li;
    li.QuadPart = -1ll;//立即開始
    FILETIME duetime = { 0 };
    duetime.dwLowDateTime = li.LowPart; 
    duetime.dwHighDateTime = li.HighPart;
    SetThreadpoolTimer(ptimer, &duetime, 1/*再次調用的時間間隔*/, 0/*用來給回調函數的執行時間增加一些隨機性*/); //設置定時器
    WaitForThreadpoolTimerCallbacks(ptimer, FALSE); //調試發現,TimerCB沒機會執行,也沒有阻塞主線程啊!?
    bres = IsThreadpoolTimerSet(ptimer); //檢查定時器狀態

    //在內核對象觸發時調用一個函數
    PTP_WAIT pwait = CreateThreadpoolWait(WaitCB, NULL, nullptr); //創建線程池等待對象
    HANDLE hevent = CreateEvent(nullptr, FALSE, TRUE, nullptr);
    SetThreadpoolWait(pwait, hevent, nullptr); //綁定到線程池
    WaitForThreadpoolWaitCallbacks(pwait, FALSE);

    //在異步IO請求完成時調用一個函數
    HANDLE hFile = CreateFile(TEXT("第11章 Windows線程池.cpp"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr);
    PTP_IO pio = CreateThreadpoolIo(hFile, IoCB, nullptr, nullptr); //創建線程池IO對象
    char buf[_MAX_PATH] = { 0 };
    OVERLAPPED ol = { 0 };
    StartThreadpoolIo(pio); //每次IO調用之前,都要調用StartThreadpoolIo啟用線程池IO對象
    bres = ReadFile(hFile, buf, _MAX_PATH, nullptr, &ol);
    StartThreadpoolIo(pio);
    bres = ReadFile(hFile, buf, _MAX_PATH, nullptr, &ol);
    WaitForThreadpoolIoCallbacks(pio, FALSE);
    StartThreadpoolIo(pio);
    CancelThreadpoolIo(pio); //撤銷線程池IO對象
    bres = ReadFile(hFile, buf, _MAX_PATH, nullptr, &ol);

    system("pause");

    SetThreadpoolTimer(ptimer, nullptr, 0, 0); //取消定時器
    CloseThreadpoolTimer(ptimer);
    ptimer = nullptr;

    SetThreadpoolWait(pwait, nullptr, nullptr);
    CloseThreadpoolWait(pwait);
    pwait = nullptr;
    CloseHandle(hevent);
    hevent = nullptr;

    //CloseThreadpoolIo(pio);  //調用CancelThreadpoolIo之後不用CloseThreadpoolIo了
    pio = nullptr;

    CloseHandle(hFile);
    hFile = nullptr;

    return 0;
}

Windows核心編程:第11章 Windows線程池