В вашем коде отсутствует необходимая синхронизация.Здесь у вас есть гонка данных .Таким образом, то, что вы получаете, является строго неопределенным поведением.Скорее всего, случится так, что компилятор просто не будет повторно извлекать значение hiddenWindowHandle
из памяти на каждой итерации цикла, поскольку он может просто предполагать, что значение не изменяется.Одним из возможных решений было бы сделать hiddenWindowHandle
std::atomic
и заставить основной поток выполнить ожидание, пока значение не изменится с NULL
.В качестве альтернативы вы можете поместить весь доступ к общей переменной в критическую секцию, заблокированную мьютексом , или использовать условную переменную , чтобы дождаться, когда значение станет доступным.
Редактирование на основе комментариев:
Так что, если я правильно понимаю ваш код, поток, который создает окно, получает указатель на переменную результата в виде void*
, а затем пытается передать результат следующим образомитак:
unsigned int __stdcall windowsPowerThread(void* data)
{
…
HWND hwHandle = *(HWND*)data;
hwHandle = hiddenWindowHandle;
…
}
Здесь есть две проблемы.Прежде всего, data
не указывает на HWND
, он указывает на std::atomic<HWND>
сейчас, так что у вас уже есть неопределенное поведение там.Основная проблема и, вероятно, объяснение того, почему ваш исходный код не работал так или иначе, несмотря на гонку данных, заключается в том, что вы создаете новый локальный HWND
с именем hwHandle
.Эта локальная переменная инициализируется значением, на которое указывает data
.Затем вы присваиваете свой результат этой локальной переменной, но не фактической переменной результата.
То, что вы хотите сделать, это сделать что-то похожее на
unsigned int __stdcall windowsPowerThread(void* data)
{
…
HWND hiddenWindowHandle = createHiddenWindow(…);
*static_cast<std::atomic<HWND>*>(data) = hiddenWindowHandle;
…
}
Вы также можете захотетьрассмотрите возможность использования std::thread
вместо необработанных функций CRT.