专栏首页C++Windows核心编程:第11章 Windows线程池

Windows核心编程:第11章 Windows线程池

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;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Windows核心编程:第9章 用内核对象进行线程同步

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

    gongluck
  • Windows核心编程:第4章 进程

    gongluck
  • Windows核心编程:第8章 用户模式下的线程同步

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

    gongluck
  • TS 常见问题整理(60多个,持续更新ing)

    不应该在模块中使用命名空间或者说将命名空间导出: 使用命名空间是为了提供逻辑分组和避免命名冲突,模块文件本身已经是一个逻辑分组,并且它的名字是由导入这个模块的代...

    coder_koala
  • 细说Golang的JSON解析

    之前一直写一些动态语言,觉得解析JOSN还是很简单的,往往只需要几行代码就能拿到解析好的JSON对象。Go语言自带的json包可以让您在程序中方便的读取和写入 ...

    mojocn
  • 理解DNS记录以及在渗透测试中的简单应用

    DNS (Domain Name System, 域名系统 ),万维网上作为域名和IP地址相互映射的一个 分布式数据库,能够使用户更方便的访问互联网,而不用去记...

    FB客服
  • 网络协议笔记(一):HTTP协议基础知识

    1、HTTP协议是超文本传输协议,也就是 HyperText Transfer Protocol。 2、HTTP是一个用在计算机世界里的协议。它使用计算机能够理...

    free赖权华
  • 小白搭建博客教程-域名解析(3)

    2016-06-1015:56:17 发表评论 1,115℃热度 上一回说道:小白搭建博客教程之流程,这次趁着端午节写完它,也算是一个了结。 ? 教程有4篇:...

    timhbw
  • docker学习(6) docker中搭建java服务及nginx反向代理

    上图中mysql容器的搭建见上篇博客,service1/2为java rest service,创建脚本如下:

    菩提树下的杨过
  • AS1.0(2.0)中的XML示例

    虽然Flash早就升级为AS3.0,但是FMS的服务端编程依然仅支持AS1.0(2.0),服务端与.net通讯的最简单方式莫过于请求一个RESTful的webS...

    菩提树下的杨过

扫码关注云+社区

领取腾讯云代金券