Re: Multithreading stuff



I came up with idea to use Cond::timed_wait instead of Glib::usleep.
This way the waiting can be interrupted, and thread can exit safely.

Thanks for the suggestions and the info.


On Sun, 2010-06-27 at 11:09 +0100, Chris Vine wrote:
> On Sun, 27 Jun 2010 09:17:19 +0200
> michi7x7 <mailing-lists michi7x7 de> wrote:
> > 
> > Chris Vine wrote:
> > > This won't work.  The default constructor of a dispatcher will
> > > cause its callbacks to execute in the main program thread (it can
> > > be constructed to execute in another thread if that other thread
> > > has its own main loop, but your worker thread doesn't have one).
> > > Apart from that, connecting to a dispatcher object is only thread
> > > safe if the connection is made in the same thread as that in which
> > > the callback will execute, which you don't do, and it must also be
> > > constructed in that thread.
> > >
> > > I am also not sure that a dispatcher can be created as a global
> > > object because at the time of creating it, g_thread_init() will not
> > > have been called (I am not sure about that one).
> > >
> > > The trite answer to the OP's problem is that if the OP doesn't know
> > > how to do something as simple as this, he probably shouldn't be
> > > programming with threads because he stands to get quite a few other
> > > things wrong. The more helpful answer is that given the awful
> > > design (looping with usleep() in the worker thread), he can have a
> > > flag which is set by the main program thread and which is read on
> > > each iteration by the worker thread which tells the worker thread
> > > to exit by throwing Glib::Thread::Exit.
> > >
> > > To be standard conforming, the flag ought to be protected by a mutex
> > > or be a glib atomic type (I don't think atomic operations are
> > > wrapped in glibmm but if not the glib C interface can be used).
> > >
> > > Chris
> > >    
> > So it's only possible if he had a seperate Glib::MainLoop within this 
> > new Thread?
> > And instead of using usleep he should use SignalTimeout, am i right?
> > 
> > So Michael, you could use either SignalTimeout on the MainLoop run by 
> > the Main-Program, or create a new MainLoop which then runs within 
> > another thread.
> > 
> > Main-Program
> > -> MainLoop
> > Thread-Programm
> > -> MainLoop
> > --> SignalTimeout
> > 
> > But you can't use a Dispatcher to kill this second thread here
> > either, because it will only get called, if the MainLoop continues
> > running. There is no way to kill threads in Glibmm, so you should
> > simply avoid calling blocking functions.
> > http://www.mail-archive.com/gtkmm-list gnome org/msg03468.html
> 
> You can use Glib::Dispatcher to cause the worker thread to execute a
> callback if it has its own main loop.  However, you cannot throw
> Glib::Thread::Exit in such a callback as the glib main loop has C
> linkage specification and cannot propagate C++ exceptions.  You could
> call g_thread_exit(), but if that is done destructors of any objects on
> the stack will not be called with windows nor with linux/BSD
> distributions using linuxthreads as opposed to NPTL. That is not a
> problem if all objects with destructors are constructed in free store
> and clean up is done manually using delete/delete[] before
> g_thread_exit() is called.
> 
> Contrary to what the message you reference says, it is safe for the
> main thread to call pthread_cancel() on the worker thread directly if
> using NPTL (which all recent, say last 4 years, linux/BSD distributions
> use) in a Unix-like environment.  NPTL will cause the stack to unwind
> with a pseudo-exception. It is safe to call pthread_cancel() even in
> linuxthreads if there are no local objects with destructors on the
> stack (that is, they are all constructed on free store) and all clean-up
> is done with pthread_cleanup_push() and pthread_cleanup_pop() with
> handlers which call delete/delete[] by hand.  For that purpose, you
> can (and should) choose the cancellation point with
> pthread_setcancelstate() so that cancellation only actually occurs when
> a suitable point in the code is reached. This won't help if the OP is
> using windows of course.
> 
> If these pre-conditions are met, calling pthread_cancel() is in my view
> the optimal solution.  Another way of achieving something similar is to
> call pthread_kill() which will send a signal to the worker thread.  The
> signal handler can set a flag for the worker thread to inspect
> periodically.  The signal will also interrupt any blocking system calls
> in the worker thread with a EINTR error provided that the SA_RESTART
> flag has not been set with sigaction(), and the worker thread can then
> arrange to terminate itself by throwing Glib::Thread::Exit if it does
> not have its own glib main loop, or calling g_thread_exit() if it has
> (as to which see my first paragraph above).
> 
> Chris
> _______________________________________________
> gtkmm-list mailing list
> gtkmm-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtkmm-list




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