VC++:释放使用 openMP 构建的 DLL 时崩溃

VC++: crash when freeing a DLL built with openMP

我已将崩溃减少到以下玩具代码:

// DLLwithOMP.cpp : build into a dll *with* /openmp
#include <tchar.h>
extern "C"
{
   __declspec(dllexport)  void funcOMP()
   {
#pragma omp parallel for
    for (int i = 0; i < 100; i++)
        _tprintf(_T("Please fondle my buttocks\n"));
   }
}

_

// ConsoleApplication1.cpp : build into an executable *without* /openmp

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

typedef void(*tDllFunc) ();

int main()
{
    HMODULE hDLL = LoadLibrary(_T("DLLwithOMP.dll"));
    tDllFunc pDllFunc = (tDllFunc)GetProcAddress(hDLL, "funcOMP");
    pDllFunc();
    FreeLibrary(hDLL);
    // At this point the omp runtime vcomp140[d].dll refcount is zero 
    // and windows unloads it, but the omp thread team remains active.
    // A crash usually ensues.
    return 0;
}

这是 MS 的错误吗?是否有一些 OMP 线程清理 API 我错过了 (probably not, but maybe)? I don't have other compilers under hand. Do they treat this scenario differently? (again, probably not) OMP 标准对这种情况有什么要说的吗?

我得到了an answer from Eric Brumer @ MS Connect。 Re-posting 以防将来有人感兴趣:

for optimal performance, the openmp threadpool spin waits for about a second prior to shutting down in case more work becomes available. If you unload a DLL that's in the process of spin-waiting, it will crash in the manner you see (most of the time).

You can tell openmp not to spin-wait and the threads will immediately block after the loop finishes. Just set OMP_WAIT_POLICY=passive in your environment, or call SetEnvironmentVariable(L"OMP_WAIT_POLICY", L"passive"); in your function before loading the dll. The default is "active" which tells the threadpool to spin wait. Use the environment variable, or just wait a few seconds before calling FreeLibrary.