Во-первых, давайте сначала исправим проблему с большей производительностью. Ваш основной поток Win32 крутится без ожидания. Это сведет на нет любое воспринимаемое различие в производительности между bool без блокировки и std :: atomic.
Вы сожжете все ядро, просто вызывая PeekMessage с избыточностью в пустой очереди. Поэтому вместо этого:
while (SystemOnline)
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
SystemOnline = false;
}
else if (!TranslateAccelerator(msg.hwnd, NULL, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
Давайте сделаем следующее, которое в точности эквивалентно тому, что у вас есть выше, за исключением того, что GetMessage
будет блокироваться, пока не поступит входящее сообщение. И GetMessage возвращает FALSE при удалении сообщения WM_QUIT.
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, NULL, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
SystemOnline = false;
И, как уже отмечали другие, преобразование из глобального bool в атомарное довольно просто:
Просто измените этот глобальный:
// Global variable in its own .h file
extern volatile bool SystemOnline;
// Initialization in a .cpp file
volatile bool SystemOnline = true;
Для этого:
// Global variable in its own .h file
#include <atomic>
extern std::atomic<bool> SystemOnline;
// Initialization in a .cpp file
std::atomic<bool> SystemOnline(true);
Вы также можете использовать std::atomic_bool
- это typedef для std::atomic<bool>
И это все, что вам нужно сделать,Вам даже не нужно менять код потока, поскольку оператор ()
для этого типа просто вызывает метод load()
для объекта. Точно так же присваивание = false
в конце цикла основного потока аналогично вызову SystemOnline.store(false)
.
Как отмечали другие, на самом деле не так уж много потери производительности для использования атомарного,На x86 он сопоставляется с префиксом кода операции LOCK .