What am I doing wrong? Memory leaks with Concurrency::samples::task_scheduler

質問 What am I doing wrong? Memory leaks with Concurrency::samples::task_scheduler

  • Friday, July 06, 2012 2:19 PM
     
      Has Code

    I must be doing something wrong.  I have a simple 32-bit Console app. I am running it on Windows 7 x64. I use Visual Studio 2010 SP1.

    The sample code pasted below leaks memory (according to Private Bytes in perfmon).

    All it does is shedule a 1 sec duration task in a task scheduler every time the ENTER key is hit.

    If you hold down the ENTER key you will see memory climb in perfmon as tasks are queued quicker than they can execute.

    When you stop holding down the ENTER key, the task pool runs dry like you would expect, but Private Bytes never drops.

    If you hit X to delete the task_scheduler instance you will see memory drop in perfmon but never as low as when the app starts.

    Looking at my exe's threads in ProcessExplorer I see lots of these:

    <tid>  MSVCRT100.dll?_IsCanceling@_TaskCollection@details@Concurrency@@QAE_NXZ+0x70b

    with stack traces that look like this:

    ntoskrnl.exe!KeWaitForMultipleObjects+0xc0a
    ntoskrnl.exe!KeAcquireSpinLockAtDpcLevel+0x732
    ntoskrnl.exe!KeWaitForMutexObject+0x19f
    ntoskrnl.exe!__misaligned_access+0xba4
    ntoskrnl.exe!__misaligned_access+0x1821
    ntoskrnl.exe!KeAcquireSpinLockAtDpcLevel+0x93d
    ntoskrnl.exe!KeWaitForMutexObject+0x19f
    ntoskrnl.exe!NtWaitForSingleObject+0xde
    ntoskrnl.exe!KeSynchronizeExecution+0x3a23
    wow64cpu.dll!TurboDispatchJumpAddressEnd+0x6c0
    wow64cpu.dll!TurboDispatchJumpAddressEnd+0x4a8
    wow64.dll!Wow64SystemServiceEx+0x1ce
    wow64.dll!Wow64LdrpInitialize+0x429
    ntdll.dll!RtlIsDosDeviceName_U+0x24c87
    ntdll.dll!LdrInitializeThunk+0xe
    ntdll.dll!ZwWaitForSingleObject+0x15
    kernel32.dll!WaitForSingleObjectEx+0x43
    kernel32.dll!WaitForSingleObject+0x12
    MSVCR100.dll!?_IsCanceling@_TaskCollection@details@Concurrency@@QAE_NXZ+0x61d
    MSVCR100.dll!?_IsCanceling@_TaskCollection@details@Concurrency@@QAE_NXZ+0x719
    kernel32.dll!BaseThreadInitThunk+0x12
    ntdll.dll!RtlInitializeExceptionChain+0x63
    ntdll.dll!RtlInitializeExceptionChain+0x36


    I am trying to use the task_scheduler as a really simple thread pool in my app. I thought I could use the schedule_task method to dispatch asynchronous events from my class.

    What am I doing wrong? Thanks.

    Here is the example code:

    #include "stdafx.h"
    #include "ConcRTExtras/concrt_extras.h"
    //==============================================================================
    int _tmain(int argc, _TCHAR* argv[])
    {
        // use the task_scheduler from concrt_extras.h
        Concurrency::samples::task_scheduler* pTaskScheduler = nullptr;
        while (true)
        {
            wprintf_s(L"Hit ENTER to schedule task (X to exit):");
            int c = _getch_nolock();
            // quit the loop?
            if (c == 'x' || c == 'X') {break;}
            _putch_nolock('\n');        
            if (pTaskScheduler == nullptr)
            {
                pTaskScheduler = new Concurrency::samples::task_scheduler();
            }
            // schedule a long-lived task
            pTaskScheduler->schedule_task([]
            {
                // this speeds things up but makes no difference to mem usage
                Concurrency::scoped_oversubcription_token overSubscribe;
                Sleep(1000);
            });
        }
        delete pTaskScheduler;
        wprintf_s(L"Hit ENTER to exit:\n");
        _getch_nolock();
        return 0;
    }


    EDIT:

    I get the same kind of leaks when I use the sample code show here in MSDN: http://msdn.microsoft.com/en-us/library/ee624185.aspx

    • Edited by dripfeed Friday, July 06, 2012 3:49 PM
    •