I've reduced a crash to the following toy code:
// DLLwithOMP.cpp : build into a dll *with* /openmp #includeextern "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#include #include 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; }
Is this an MS bug? Is there some OMP thread-cleanup API I missed (probably not, but maybe)? I don't have other compilers under hand. Do they treat this scenario differently? (again, probably not) Does the OMP standard has anything to say on such a scenario?
我从Eric Brumer @ MS Connect那里得到了答案。如果将来有人对它感兴趣,请在此处重新发布:
为了获得最佳性能,如果有更多工作可用,则openmp线程池旋转将在关闭之前等待一秒钟。如果卸载正在等待旋转的DLL,它将以您看到的方式崩溃(大多数时间)。
您可以告诉openmp不要旋转等待,并且线程会在循环结束后立即阻塞。只需在您的环境中设置OMP_WAIT_POLICY = passive,或调用SetEnvironmentVariable(L“ OMP_WAIT_POLICY”,L“ passive”); 在您的函数中,然后再加载dll。默认值为“ active”,它告诉线程池旋转等待。使用环境变量,或者等待几秒钟再调用FreeLibrary。