Re: Thread problem in Windows
- From: Chris Vine <chris cvine freeserve co uk>
- To: Filipe Apostolo <f apostolo cbr gmail com>
- Cc: gtkmm-list gnome org
- Subject: Re: Thread problem in Windows
- Date: Tue, 22 Sep 2009 20:01:27 +0100
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?
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.
* 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
* 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.
 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
] [Thread Prev