Usar Glib::Dispatcher

Los «slots» conectados a objetos sigc::signal se ejecutan en el hilo que llama a emit() u operator()() en la señal. Glib::Dispatcher no se comporta de esa manera: en su lugar, sus «slots» conectados se ejecutan en el hilo en el que el objeto Glib::Dispatcher se construyó (que debe tener un bucle principal de glib). Si un objeto Glib::Dispatcher se construye en el hilo principal de la IGU (que por ende será el hilo receptor), cualquier hilo de trabajo puede emitir sobre él y sus «slot» conectados podrán ejecutar funciones de gtkmm con seguridad.

Aún así, algunas reglas de seguridad de hilos sobre el uso de Glib::Dispatcher se aplican. Como se mencionó, un objeto Glib::Dispatcher debe construirse en el hilo receptor (aquel en cuyo bucle principal ejecutará sus «slot» conectados). Por defecto este es el hilo principal del programa, a pesar de que hay un constructor Glib::Dispatcher que toma el objeto Glib::MainContext de cualquier hilo que tiene un bucle principal. Solo el hilo receptor debe llamar a connect() en el objeto Glib::Dispatcher, o manipular cualquier objeto sigc::connection relacionado, a menos que se emplee sincronización adicional. Sin embargo, cualquier hilo de trabajo puede emitir con seguridad en el objeto Glib::Dispatcher sin bloquear una vez que el hilo receptor ha conectado los «slot», siempre que se construya antes de que el hilo de trabajo arranque (si se construye después, normalmente se requerirá sincronización adicional para asegurar la visibilidad).

Aside from the fact that connected slots always execute in the receiver thread, Glib::Dispatcher objects are similar to sigc::signal<void()> objects. They therefore cannot pass unbound arguments nor return a value. The best way to pass unbound arguments is with a thread-safe (asynchronous) queue. At the time of writing glibmm does not have one, although most people writing multi-threaded code will have one available to them (they are relatively easy to write although there are subtleties in combining thread safety with strong exception safety).

A Glib::Dispatcher object can be emitted on by the receiver thread as well as by a worker thread, although this should be done within reasonable bounds. On unix-like systems Glib::Dispatcher objects share a single common pipe, which could in theory at least fill up on a very heavily loaded system running a program with a very large number of Dispatcher objects in use. Were the pipe to fill up before the receiver thread's main loop has had an opportunity to read from it to empty it, and the receiver thread attempt to emit and so write to it when it is in that condition, the receiver thread would block on the write, so deadlocking. Where the receiver thread is to emit, a normal sigc::signal<void()> object could of course be used instead.