中断或加入后重用Boost线程(来自线程池)
目前,我正在使用生产者消费者模型来进行实时图形应用程序的渲染部分。消费者将不断地在我们的队列中寻找数据(无限循环);但是我担心这可能会导致我的模拟与主循环不同步。我认为这是快速生产者缓慢消费者问题 - 由于模拟被限制在一定的时间内,这一问题变得更加复杂。
问题 - 保持这一切平衡并确保消费者有足够的时间完成的最佳方法是什么,而且在完成之前模拟不会移动到下一帧渲染我们当前的帧(或者至少能够检测到这一点并跳过渲染下一帧 - 或中断当前正在渲染的帧) 我目前只是在每个消费者完成后中断并加入
第二个问题: 如果您查看下面的代码,您会发现我当前只是在将渲染作业添加到队列后调用中断和加入 - 这允许线程在完成其操作所需的所有时间中,并响应完成后中断。 在调用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();
我试图使这个简单快速消化,谢谢您的宝贵时间
At the moment I am using a producer consumer model for the rendering portion of a realtime graphics application. The consumer will continually look for data in our queue(infinite loop); however I am fearful that this may cause my simulation to get out of sync of the main loop. I think this is the fast producer slow consumer problem - compounded by the fact that the simulation is restrained to a certain amount of time.
Question - what is the best method to keep this all in balance and make sure the consumer has enough time to finish, but also that the simulation does not move to the next frame before we are finished rendering our current frame(or at least be able to detect this and skip rendering the next frame - or interrupt the current frame being rendered) I am currently just interrupting and joining after each consumer is finished
Second Question: if you look at the code below you will see that I am currently just calling interrupt and join after adding rendering jobs to the queue - this allows the thread all the time it needs to complete its operation, and to respond to the interrupt when finished. How can I then reuse threads in a thread pool after interrupt_all and join_all are called? (i.e. if i call drawNextFrame again)
The producer is part of the main thread of execution (I don't think this affects anything)
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)
if you need to look at the consumer class see below:
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();
I tried to make this simple and quick to digest, thank you for your time
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
#1.我会通过在每次渲染后计算队列中的数量来完成此操作。如果太高,那么要么
a。转储队列
B.将布尔变量设置为 false
该变量将在线程之间共享,当生产者发现它为假时,它开始等待条件变量。当队列再次下降到可接受的水平时,消费者会通知生产者。
#2. join_all 可能不可能,因为 join_all 的后置条件是
根据参考。
然而,使用屏障而不是 join_all 是可能的,但是您必须找到一种方法来向它们提供数据,这最终总是需要更多的共享变量。
#1. I would do this by counting the amount in the queue after each render. If it too high, then either
a. Dump the queue
b. Set a boolean variable to false
That variable will be shared between the threads, and when the producer sees that it is false, it begins waiting on a condition variable. The consumer then notifies the producer when the queue is down to an acceptable level again.
#2. Probably not possible with join_all, as the postcondition to join_all is
according to the reference.
It might however be possible, using barriers instead of join_all, but then you would have to find a way to provide them data, which would invariably end up needing some more shared variables.