I have a programming that is drawing realtime animations to a gtkmm window. I have my main thread gui thread and a worker threa that renders a frame of the animation to a image surface using cairo. The w开发者_开发问答orker thread has is signaled by the main thread every 33mS. Right now I have my app creating a new rendering thread on every timeout when a frame has to be rendered. How can I go about creating a kind of thread pool where on timeout in the gui thread signals my worker thread to wakeup and render a frame which signals the gui thread that frame is complete then go back to sleep and wait to be signaled again.
I am not an expert in rendering and cairo, but threads can in general signal each other. An easier way to do same is to use conditional variable or mutex. All your worker threads can wait on mutex and GUI thread can release mutex on time out and GUI thread itself can go and wait on another thread. Worker thread on acquiring mutex can render frame and signal GUI thread and then can go back to first mutex to wait for next signal from GUI thread.
You could use a master-worker
approach, where the main thread is the master
that handles frames to be rendered and the workers
are extracted from a pool
of worker threads.
There is a public domain thread pool
implementation available from DevGuy that you can use.
I think something like this should work:
#include <dg/dg.h>
#include <dg/thread/threadpool.h>
#include <dg/thread/impl.h>
#include <dg/impl.h>
#include <boost/bind.hpp>
// a mutex is needed if the workers touch shared data
boost::mutex mutex;
struct work
{
void operator ()()
{
boost::mutex::scoped_lock lock(mutex);
// this is where a worker does its thing
}
worker(/* your constructor params */)
{
// ...
}
worker(const worker &w)
{
// ...
}
// internal work data
};
int main(int argc, char* argv[])
{
// a pool with 5 threads that ca queue up to 100 jobs
dg::thread::ThreadPool pool(5,100);
for (;;)
{
// create a piece of work
work w;
// execute the work
pool.invoke(w);
// some exit condition
}
// wait for unfinished work
pool.wait();
}
Here is another usage example.
精彩评论