Я делаю код многопоточной видеоигры. Прежде чем приступить к программированию, я просмотрел статью, в которой смутно описывалось решение 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, прежде чем другой поток начнет ждать, и вся система застрянет в ожидании навсегда.
Я не могу найти простой способ решить эту проблему. Мне очень нравится этот подход, потому что синхронизация не останавливается, пока какой-то независимый поток выполняет синхронизацию.
Я ценю любые идеи или предложения, которые кто-либо может предложить.