views:

38

answers:

2

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 worker 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.

+1  A: 

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.

Rohit
Yea I figured cross thread signal would be the best way. Maybe the Glib::Dispatcher is what I need to make this work
Talguy
A: 

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.

the_void