none
Does OpenMP when used in threads leak thread handles and memory? RRS feed

  • Question

  • Hi.

    I have begun to experiment with OpenMP lately. I noticed that C++ programs
    with OpenMP clauses compiled with the C++ compiler of Visual Studio 2005
    and 2008 seems to leak thread handles and memory if OpenMP is used in
    threads other than the main thread.

    I have attached a code sample below that should demonstrate my problem.
    The main function in my code creates new threads and executes them in
    a loop. The thread contains an OpenMP parallelized loop. After a thread
    has finished the OpenMP allocated threads + resources of the thread will
    not be released.

    Am I doing something wrong here or is this a limitation of the Visual C++
    OpenMP implementation? Is it required to release OpenMP allocated resourced
    in threads by hand? My sample compiled with the current Intel C++ compiler
    does not have such effects.

    Please advice!

    Code Block

    // command line application, compile with OpenMP support

    #include <Windows.h>
    #ifdef _OPENMP
    #include <omp.h>
    #endif

    DWORD WINAPI threadFunc(LPVOID lpParam)
    {    
        #pragma omp parallel for
        for (int y = 0; y < 100; ++y)
        {
        }       
        return 0;
    }

    int main(int argc, char* argv[])
    {
    #ifdef _OPENMP
        const int numOmpThreads = 3;
        omp_set_num_threads(numOmpThreads);
    #endif

        for (int i = 0; i < 10; ++i)
        {
            // will leak numOmpThreads-1 thread handles and memory per iteration
            DWORD threadId = 0;
            HANDLE threadHandle = CreateThread(0, 0, threadFunc, 0, CREATE_SUSPENDED, &threadId);

            SetThreadPriority(threadHandle, GetThreadPriority(GetCurrentThread()));       
            ResumeThread(threadHandle);
            WaitForSingleObject(threadHandle, INFINITE);
            CloseHandle(threadHandle);
        }

        return 0;
    }



    Friday, November 30, 2007 2:30 PM

Answers

  • OK, uninitialized CRT state was a wild guess.

     

    From what I can see looking at the OMP specification, you're in territory not covered explicitly by the specification.  That said, what you describe sounds like a bug, not a feature.  I'd suggest submitting a bug report at:

     

    http://connect.microsoft.com/VisualStudio/Feedback.

     

    Friday, November 30, 2007 8:28 PM
    Moderator

All replies

  • A wild guess - have you tried creating the threads using _beginthredex instead of CreateThread?  If you're statically linking the runtime library, then threads created with CreateThread will have an uninitialized CRT state, which might cause problems like this.  If you're using the DLL version of the CRT it doesn't matter which you use as the CRT state gets initialized as a result of DLL_THREAD_ATTACH in the CRL DLL.

     

    Friday, November 30, 2007 5:48 PM
    Moderator
  • As in my sample code I do use CreateThread for creating threads and I link against the dynamic CRT so I don't think there is a problem with an uninitialized CRT state.
    Friday, November 30, 2007 6:28 PM
  • OK, uninitialized CRT state was a wild guess.

     

    From what I can see looking at the OMP specification, you're in territory not covered explicitly by the specification.  That said, what you describe sounds like a bug, not a feature.  I'd suggest submitting a bug report at:

     

    http://connect.microsoft.com/VisualStudio/Feedback.

     

    Friday, November 30, 2007 8:28 PM
    Moderator
  • I haved experienced the same problem. Using your code as a base, use the omp_set_dynmaic() command.

    For example

    #ifdef _OPENMP
        const int numOmpThreads = 3;
        omp_set_num_threads(numOmpThreads);
        omp_set_dynamic(4);
    #endif

    With this I did not leak any threads. This does change the thread usage, however, it should not be a major problem considering the alternative is a quick failure.
    • Proposed as answer by LarsV Monday, March 8, 2010 12:26 AM
    Thursday, April 17, 2008 5:56 PM
  • I haved experienced the same problem. Using your code as a base, use the omp_set_dynmaic() command.

    For example

    #ifdef _OPENMP
        const int numOmpThreads = 3;
        omp_set_num_threads(numOmpThreads);
        omp_set_dynamic(4);
    #endif

    With this I did not leak any threads. This does change the thread usage, however, it should not be a major problem considering the alternative is a quick failure.

    Yep that fixed the problem for me.
    Monday, March 8, 2010 12:27 AM