zoukankan      html  css  js  c++  java
  • Windows线程池Demo

    #include <windows.h>
    #include <tchar.h>
    #include <stdio.h>

    //
    // Thread pool wait callback function template
    //
    VOID
        CALLBACK
        MyWaitCallback(
        PTP_CALLBACK_INSTANCE Instance,
        PVOID                 Parameter,
        PTP_WAIT              Wait,
        TP_WAIT_RESULT        WaitResult
        )
    {
        //
        // Do something when the wait is over.
        //
        _tprintf(_T("MyWaitCallback: wait is over.\n"));
    }


    //
    // Thread pool timer callback function template
    //
    VOID
        CALLBACK
        MyTimerCallback(
        PTP_CALLBACK_INSTANCE Instance,
        PVOID                 Parameter,
        PTP_TIMER             Timer
        )
    {
        //
        // Do something when the timer fires.
        //
        _tprintf(_T("MyTimerCallback: timer has fired.\n"));

    }


    //
    // This is the thread pool work callback function.
    // The callback demonstrates correct behavior when changing the
    // state of the thread inside the callback function.
    //
    // Any changes to the thread state must be restored to original
    // before exiting the callback routine.
    //
    VOID
        CALLBACK
        MyWorkCallback(
        PTP_CALLBACK_INSTANCE Instance,
        PVOID                 Parameter,
        PTP_WORK              Work
        )
    {
        BOOL bRet = FALSE;
        DWORD dwPriorityOriginal = 0;

        //
        // Record the original thread priority.
        //
        dwPriorityOriginal = GetThreadPriority(GetCurrentThread());

        if (THREAD_PRIORITY_ERROR_RETURN == dwPriorityOriginal) {
            _tprintf(_T("GetThreadPriority failed.  LastError: %u\n"),
                GetLastError());
            return;
        }

        //
        // Increase the priority of the thread pool thread.
        //
        bRet = SetThreadPriority(GetCurrentThread(),
            THREAD_PRIORITY_ABOVE_NORMAL);

        if (FALSE == bRet) {
            _tprintf(_T("SetThreadPriority failed.  LastError: %u\n"),
                GetLastError());
            return;
        }

        _tprintf(_T("MyWorkCallback: thread priority increased.\n"));


        //
        // Perform tasks at increased priority.
        //
        {
            _tprintf(_T("MyWorkCallback: task performed at increased priority.\n"));

        }

        //
        // Restore thread state by resetting the original priority.
        //
        bRet = SetThreadPriority(GetCurrentThread(),
            dwPriorityOriginal);

        //
        // If restore fails, maybe retry or throw an exception.  Otherwise,
        // the thread will continue to execute other work items at increased
        // priority.
        //
        if (FALSE == bRet) {
            _tprintf(_T("Fatal Error! SetThreadPriority failed. LastError: %u\n"),
                GetLastError());
            return;
        }

        _tprintf(_T("MyWorkCallback: thread priority restored.\n"));

        return;
    }

    VOID
        DemoCleanupPersistentWorkTimer()
    {
        BOOL bRet = FALSE;
        PTP_WORK work = NULL;
        PTP_TIMER timer = NULL;
        PTP_POOL pool = NULL;
        PTP_WORK_CALLBACK workcallback = MyWorkCallback;
        PTP_TIMER_CALLBACK timercallback = MyTimerCallback;
        TP_CALLBACK_ENVIRON CallBackEnviron;
        PTP_CLEANUP_GROUP cleanupgroup = NULL;
        FILETIME FileDueTime;
        ULARGE_INTEGER ulDueTime;
        UINT rollback = 0;

        InitializeThreadpoolEnvironment(&CallBackEnviron);

        //
        // Create a custom, dedicated thread pool.
        //
        pool = CreateThreadpool(NULL);

        if (NULL == pool) {
            _tprintf(_T("CreateThreadpool failed. LastError: %u\n"),
                GetLastError());
            goto main_cleanup;
        }

        rollback = 1; // pool creation succeeded

        //
        // The thread pool is made persistent simply by setting
        // both the minimum and maximum threads to 1.
        //
        SetThreadpoolThreadMaximum(pool, 1);

        bRet = SetThreadpoolThreadMinimum(pool, 1);

        if (FALSE == bRet) {
            _tprintf(_T("SetThreadpoolThreadMinimum failed. LastError: %u\n"),
                GetLastError());
            goto main_cleanup;
        }

        //
        // Create a cleanup group for this thread pool.
        //
        cleanupgroup = CreateThreadpoolCleanupGroup();

        if (NULL == cleanupgroup) {
            _tprintf(_T("CreateThreadpoolCleanupGroup failed. LastError: %u\n"),
                GetLastError());
            goto main_cleanup;
        }

        rollback = 2;  // Cleanup group creation succeeded

        //
        // Associate the callback environment with our thread pool.
        //
        SetThreadpoolCallbackPool(&CallBackEnviron, pool);

        //
        // Associate the cleanup group with our thread pool.
        // Objects created with the same callback environment
        // as the cleanup group become members of the cleanup group.
        //
        SetThreadpoolCallbackCleanupGroup(&CallBackEnviron,
            cleanupgroup,
            NULL);

        //
        // Create work with the callback environment.
        //
        work = CreateThreadpoolWork(workcallback,
            NULL,
            &CallBackEnviron);

        if (NULL == work) {
            _tprintf(_T("CreateThreadpoolWork failed. LastError: %u\n"),
                GetLastError());
            goto main_cleanup;
        }

        rollback = 3;  // Creation of work succeeded

        //
        // Submit the work to the pool. Because this was a pre-allocated
        // work item (using CreateThreadpoolWork), it is guaranteed to execute.
        //
        SubmitThreadpoolWork(work);


        //
        // Create a timer with the same callback environment.
        //
        timer = CreateThreadpoolTimer(timercallback,
            NULL,
            &CallBackEnviron);


        if (NULL == timer) {
            _tprintf(_T("CreateThreadpoolTimer failed. LastError: %u\n"),
                GetLastError());
            goto main_cleanup;
        }

        rollback = 4;  // Timer creation succeeded

        //
        // Set the timer to fire in one second.
        //
        ulDueTime.QuadPart = (LONGLONG) -(1 * 10 * 1000 * 1000);
        FileDueTime.dwHighDateTime = ulDueTime.HighPart;
        FileDueTime.dwLowDateTime  = ulDueTime.LowPart;

        SetThreadpoolTimer(timer,
            &FileDueTime,
            0,
            0);

        //
        // Delay for the timer to be fired
        //
        Sleep(1500);

        //
        // Wait for all callbacks to finish.
        // CloseThreadpoolCleanupGroupMembers also releases objects
        // that are members of the cleanup group, so it is not necessary
        // to call close functions on individual objects
        // after calling CloseThreadpoolCleanupGroupMembers.
        //
        CloseThreadpoolCleanupGroupMembers(cleanupgroup,
            FALSE,
            NULL);

        //
        // Already cleaned up the work item with the
        // CloseThreadpoolCleanupGroupMembers, so set rollback to 2.
        //
        rollback = 2;
        goto main_cleanup;

    main_cleanup:
        //
        // Clean up any individual pieces manually
        // Notice the fall-through structure of the switch.
        // Clean up in reverse order.
        //

        switch (rollback) {
        case 4:
        case 3:
            // Clean up the cleanup group members.
            CloseThreadpoolCleanupGroupMembers(cleanupgroup,
                FALSE, NULL);
        case 2:
            // Clean up the cleanup group.
            CloseThreadpoolCleanupGroup(cleanupgroup);

        case 1:
            // Clean up the pool.
            CloseThreadpool(pool);

        default:
            break;
        }

        return;
    }

    VOID
        DemoNewRegisterWait()
    {
        PTP_WAIT Wait = NULL;
        PTP_WAIT_CALLBACK waitcallback = MyWaitCallback;
        HANDLE hEvent = NULL;
        UINT i = 0;
        UINT rollback = 0;

        //
        // Create an auto-reset event.
        //
        hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

        if (NULL == hEvent) {
            // Error Handling
            return;
        }

        rollback = 1; // CreateEvent succeeded

        Wait = CreateThreadpoolWait(waitcallback,
            NULL,
            NULL);

        if(NULL == Wait) {
            _tprintf(_T("CreateThreadpoolWait failed. LastError: %u\n"),
                GetLastError());
            goto new_wait_cleanup;
        }

        rollback = 2; // CreateThreadpoolWait succeeded

        //
        // Need to re-register the event with the wait object
        // each time before signaling the event to trigger the wait callback.
        //
        for (i = 0; i < 5; i ++) {
            SetThreadpoolWait(Wait,
                hEvent,
                NULL);

            SetEvent(hEvent);

            //
            // Delay for the waiter thread to act if necessary.
            //
            Sleep(500);

            //
            // Block here until the callback function is done executing.
            //

            WaitForThreadpoolWaitCallbacks(Wait, FALSE);
        }

    new_wait_cleanup:
        switch (rollback) {
        case 2:
            // Unregister the wait by setting the event to NULL.
            SetThreadpoolWait(Wait, NULL, NULL);

            // Close the wait.
            CloseThreadpoolWait(Wait);

        case 1:
            // Close the event.
            CloseHandle(hEvent);

        default:
            break;
        }
        return;
    }

    int _tmain(int argc, _TCHAR* argv[])
    {
        DemoNewRegisterWait();
        DemoCleanupPersistentWorkTimer();
        return 0;
    }

  • 相关阅读:
    c# 让接口实现方法
    码支付 C#
    WebApi 接口返回值类型详解
    阿里云RDS数据库sql server 导入数据并添加作业小结
    IIS 图片 JS CSS 500错误
    XML字符串反序列化为实体
    找不到请求的 .Net Framework Data Provider
    JS通过ClassName禁止DIV点击
    WebRequest请求被中止: 未能创建 SSL/TLS 安全通道
    NetMQ 消息队列
  • 原文地址:https://www.cnblogs.com/flying_bat/p/1771771.html
Copyright © 2011-2022 走看看