Повторное использование потока Boost (из Threadpool) после прерывания или присоединения
-
10-10-2019 - |
Вопрос
На данный момент я использую модель потребителей производителя для части рендеринга графического приложения в реальном времени. Потребитель будет постоянно искать данные в нашей очереди (Infinite Loop); Однако я боюсь, что это может привести к тому, что моя симуляция выходит из синхронизации основного цикла. Я думаю, что это быстрый производитель медленного потребителя, усугубляемая тем фактом, что моделирование ограничено определенным количеством времени.
Вопрос - Какой метод лучше всего поддерживать все это в равновесии и убедиться, что у потребителя достаточно времени, чтобы закончить, но также и то, что моделирование не перемещается в следующий кадр, прежде чем мы закончим рендеринг нашего текущего кадра (или, по крайней мере, сможем обнаружить Это и пропустить рендеринг следующего кадра - или прерывать текущий кадр, отображаемый) В настоящее время я просто прерываю и присоединяюсь после завершения каждого потребителя
Второй вопрос: Если вы посмотрите на код ниже, вы увидите, что в настоящее время я просто вызовут прерывание и присоединяюсь после добавления заданий рендеринга в очередь - это позволяет потоку все время, которое ему необходимо выполнить, и ответить на прерывание, когда закончено. Как я могу затем повторно использовать потоки в пуле потоков после вызова Enterrupt_all и join_all? (т.е. если я снова позвоню в DraitNextFrame)
Производитель является частью основного потока исполнения (я не думаю, что это повлияет на что -либо)
pseudo code:
void renderSystem::init()
create queue to hold work;
create consumer threads of type RenderConsumer set to watch our queue;
add threads to thread_pool of consumers called 'RenderThreads'
void renderSystem::drawNextFrame()
for each thread in 'RenderThreads' divy up work;
add work assignment to queue;
//RenderThreads will now successfully start pulling data from our queue
renderThreads.interupt_all();
renderThreads.join_all();
int main()
renderer = renderSystem class;
renderer.init()
while(not_gameover)
renderer.drawNextFrame();
doOtherCoolStuff();
profit(?)
return(0)
Если вам нужно посмотреть на класс потребителей, см. Ниже:
pseudo code:
RenderConsumer::operator () ()
while(true)
try to dequeue from queue
//digest any packet we get
for each ( pixel in packet )
computePrettyStuff()
//we are now done with packet that we got
this_thread::interruption_point();
Я пытался сделать это просто и быстро переваривать, спасибо за ваше время
Решение
#1. Я бы сделал это, посчитав сумму в очереди после каждого рендеринга. Если это слишком высоко, то либо
а Сбросьте очередь
беременный Установите логическую переменную в FALSE, что переменная будет передана между потоками, и когда производитель видит, что она FALSE, она начинает ждать переменной условия. Затем потребитель уведомляет производителя, когда очередь снова допускается до приемлемого уровня.
#2. Вероятно, невозможно с join_all, так как пост -кондиционирование join_all
Каждый поток в группе прекратился.
в соответствии со ссылкой.
Однако это может быть возможно, используя барьеры вместо join_all, но тогда вам придется найти способ предоставить им данные, что неизменно в конечном итоге понадобится еще несколько общих переменных.