Повторно использовать Boost thread (из threadpool) после прерывания или соединения - PullRequest
0 голосов
/ 08 декабря 2010

В настоящее время я использую потребительскую модель производителя для части рендеринга графического приложения реального времени. Потребитель будет постоянно искать данные в нашей очереди (бесконечный цикл); однако я боюсь, что это может привести к тому, что моя симуляция выйдет из синхронизации основного цикла. Я думаю, что это проблема медленного потребителя быстрого производителя, которая усугубляется тем фактом, что симуляция ограничена определенным периодом времени.

Вопрос - Каков наилучший способ сохранить все это в равновесии и убедиться, что у потребителя есть достаточно времени, чтобы закончить, но также и то, что симуляция не переходит к следующему кадру, прежде чем мы завершили рендеринг нашего текущего кадра (или, по крайней мере, смогли обнаружить это и пропустить рендеринг следующего кадра - или прервать рендеринг текущего кадра) В настоящее время я просто прерываю и присоединяюсь после завершения каждого потребителя

Второй вопрос: Если вы посмотрите на приведенный ниже код, вы увидите, что я сейчас просто вызываю прерывание и присоединяюсь после добавления заданий рендеринга в очередь - это позволяет потоку все время, необходимое для завершения. его работа, и реагировать на прерывание, когда закончено. Как я могу затем повторно использовать потоки в пуле потоков после вызова interrupt_all и join_all? (т.е. если я снова вызову drawNextFrame)

Производитель является частью основного потока выполнения (я не думаю, что это влияет на что-либо)

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 Ответ

1 голос
/ 11 декабря 2010

# 1.Я бы сделал это, посчитав сумму в очереди после каждого рендера.Если оно слишком высокое, то либо

a.Сбросить очередь

b.Установите для логической переменной значение false. Эта переменная будет разделена между потоками, и когда производитель увидит, что она имеет значение false, он начнет ожидать условную переменную.Затем потребитель уведомляет производителя, когда очередь снова падает до приемлемого уровня.

# 2.Вероятно, невозможно с join_all, так как постусловие для join_all равно

Завершена каждая нить в группе.

согласно ссылке.

ItТем не менее, возможно, будет возможно использовать барьеры вместо join_all, но тогда вам нужно будет найти способ предоставить им данные, что неизбежно приведет к необходимости использования нескольких общих переменных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...