Re: Thread problem in Windows



On Tue, 22 Sep 2009 10:40:21 +0100
Filipe Apostolo <f apostolo cbr gmail com> wrote:
> Ok, I've never heard about Glib::Dispacher until yesterday, I will
> tray it, is there a good example or documentation for it?

It's here:

http://library.gnome.org/devel/glibmm/unstable/classGlib_1_1Dispatcher.html

There is also documentation in the examples/thread sub-directory of the
distribution tarball.  As I recall, the examples used to be defective -
they used to create a thread with a slot representing a non-static
method of a class deriving from sigc::trackable, which is not thread
safe, but I believe that has been corrected.

Using threads with libsigc++ (and therefore gtkmm) is do-able but you
have to be careful, as libsigc++ is not thread safe - amongst other
things, a class inheriting from sigc::trackable will, via that
inheritance, have a std::list object keeping track of slots connected
to any of its non-static methods. Each sigc::slot object also, via
sigc::slot_rep, keeps its own sigc::trackable object to track any
sigc::connection objects which it needs to inform about its demise.
sigc::signal objects also keep lists of slots, which will be updated
with a call to its connect() and disconnect() methods.  This requires a
few rules to be observed in multi-threaded applications:

     * Unless special additional synchronisation is employed, regard
       any particular sigc::signal object as "owned" by the thread
       which created it.  Only that thread should connect or
       disconnect slots with respect to the signal object, and only
       that thread should emit() or call operator()() on it.

     * The rules with Glib::Dispatcher are a little more relaxed.  Only
       the receiver thread (normally the main GUI thread) should create
       the Dispatcher object and call connect(), disconnect() on it
       (and manipulate any related sigc::connection object - see below)
       but any thread can call emit() on it[1].

     * Unless special additional synchronisaton is employed, regard
       any sigc::connection object as owned by the thread which
       created the slot and called the method which provided the
       sigc::connection object.  Only that thread should call
       sigc::connection methods on the object.

     * Unless you know what you are doing, do not copy slots between
       threads.  In addition never ever copy to another thread a slot
       which references a non-static method of a class derived from
       sigc::trackable.

     * If a particular class object derives from sigc::trackable, only
       one thread should create slots representing any of its
       non-static methods (ie create slots with sigc::mem_fun()).
       Regard the first thread to create such a slot as owning the
       relevant object for the purpose of creating further slots
       referencing any of its methods.

Unless you are experienced with threaded programming, you can very
easily slip up.  You need to keep a clear view of what threads are
doing what, and last point above can be a real "trip me up".

For your usage, the proposal to use a non-blocking dialog and up-date
it with a timeout is the best solution.

Chris

[1]  Actually there is a theoretical risk that if you _emit_ in
the receiver thread you could get a deadlock on unix-like
implementations, as the pipe could fill up on a very heavily loaded
system running a program with a very large number of Dispatcher objects
in use, because the same thread would both make a blocking write and
also read from the pipe.  I doubt this would ever happen in practice
though.




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