VC++: сбой при освобождении DLL, созданной с помощью 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? Есть ли какой-то API очистки потоков OMP, который я пропустил ( возможно, нет, но, возможно,)? У меня нет других компиляторов под рукой. Они относятся к этому сценарию по-другому? (опять же, вероятно, нет). Есть ли что-то, что мог бы сказать стандарт OMP по такому сценарию?

1 ответ

Решение

Я получил ответ от Эрика Брумера из MS Connect. Повторно разместите его здесь на случай, если он заинтересует кого-либо в будущем:

для достижения оптимальной производительности вращение пула потоков openmp ждет около секунды, прежде чем завершить работу, если станет доступно больше работы. Если вы выгружаете DLL, которая находится в процессе ожидания вращения, она будет аварийно завершать работу, как вы видите (большую часть времени).

Вы можете сказать openmp, что не нужно ждать вращения, и потоки будут немедленно заблокированы после завершения цикла. Просто установите OMP_WAIT_POLICY= пассив в вашей среде или вызовите SetEnvironmentVariable(L"OMP_WAIT_POLICY", L"пассивный"); в вашей функции перед загрузкой DLL. По умолчанию установлено значение "active", которое указывает пулу потоков на ожидание вращения. Используйте переменную окружения или просто подождите несколько секунд, прежде чем вызывать FreeLibrary.

Другие вопросы по тегам