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 <[email protected]> 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/[email protected]/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 > [email protected] > http://mail.gnome.org/mailman/listinfo/gtkmm-list _______________________________________________ gtkmm-list mailing list [email protected] http://mail.gnome.org/mailman/listinfo/gtkmm-list
