Я делаю несколько многопоточных кодов видеоигр.Перед тем, как начать писать код, я посмотрел статью, в которой смутно описывается решение Valve для многопоточного игрового дизайна.Ключевым понятием, которое я почерпнул из статьи, является синхронизация потоков.Я не знаю, так ли это, как Valve, но я представил несколько потоков, каждый из которых выполняет игровой цикл.В конце каждой итерации потоки приостанавливают и ждут, пока другие потоки завершат свою текущую итерацию, а затем синхронизируют общие данные.Я полагаю, что помимо издержек, связанных с этой схемой управления, было бы не иначе, чтобы позволить потокам работать полностью асинхронно.В статье упоминается тема, используемая исключительно для синхронизации, но я пытаюсь найти другое решение для правильной работы.Вот как я (пытаюсь) это сделать:
// at end of loop on each thread...
sig_thread_done();
while (!is_sync_done())
{
PauseExecution(1);
}
sig_thread_done и is_sync_done являются объектами функций из другого класса, который управляет списком всех «потоков».Эти функции выглядят так:
bool Core::IsFrameDone()
{
MutexLock lock(manager_mutex);
if (waiting_components == -1)
{
waiting_components = 0;
return true;
}
return false;
}
void Core::SignalFrameDone()
{
MutexLock lock(manager_mutex);
if (++waiting_components == (int)components.size()) // components == threads
{
//sync shared data...
waiting_components = -1; // -1 signifies that all threads have completed their iteration
}
}
Проблема в том, что быстрый поток может выйти из своего цикла ожидания и вернуться к нему снова, прежде чем другие потоки смогут выйти из него.Таким образом, другие потоки пропускают выход через is_sync_done, возвращая false, прежде чем другой поток начинает ждать, и вся система застревает в ожидании навсегда.
Я не могу найти простой способ решить эту проблему.Мне очень нравится этот подход, потому что синхронизация не останавливается, пока какой-то независимый поток выполняет синхронизацию.
Я ценю любые идеи или предложения, которые кто-либо может предложить.
Ссылка на статью.