Re: Multiple threads and drawing



Germán Diago schrieb:
I have multiple threads that calculate thumbnails of images. The
program creates a Table to contain the images.
Once an image is available (which is calculated by worker threads) , a
signal containing the image is sent from that thread
so that it can be put inside the table. Inside the slot Ithat handles
a new thumbnail available I attach the image  to the table and then
call the dispatcher(),
which calls show_all().
Is this correct?

The (simplified) code is something like this:

class GUI : public Gtk::Window
{
private:
   Glib::Dispatcher d_;
   Gtk::Table * table_;
   Gtk::Button buttonprocessimages_;
   Gtk::Label l_;
   ThreadPool & pool_;

   void onImageAvailable(...)
   {
       table_->attach(*img, row, col,...);
       d_();

   }

   void redraw()
   {
      show_all();
   }
   void processImages()
   {
       table_ = Gtk::Manage(new Gtk::Table(........
       pool_.set_max_threads(n);
       send_work_to_process...
       label_.set_text("");

       buttonprocessimages_.set_sensitive(false);
   }
public:
   GUI(Glib::ThreadPool & pool) : pool_(pool)
   {
     buttonprocessimages_.connect(sigc::mem_fun(*this, &GUI::processImages));
     signal_image_available.connect(sigc::mem_fun(*this,
&GUI::onImageAvailable));
      d_.connect(sigc::mem_fun(*this, &GUI::redraw));

   }
};

[...]

Can help, please? Maybe I'm drawing implicitly when I use
label.set_text() or table_.attach() from a non-GUI thread?
Thanks for you time.

What exactly is signal_image_available and which threads are calling it?
If the threads that are calling it are the threads from the thread pool then you would have a problem because multiple threads are attaching at the same time to the table. Just because you're using a Dispatcher the way you're using it doesn't make your code threadsafe.

As Milosz already put it: avoid accessing the GUI stuff from other threads.
It's a better idea to have an image list structure outside of the GUI class, accessible by all of your threads - you have to lock it whenever the gui thread or the worker threads update/read the list. Your redraw() handler should update the Gtk::Table with the information found in this image list (after locking it of course).

You could use a framework for interthread communication like sigx++, which is a good idea IMHO.


Klaus


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]