Používání Glib::Dispatcher

Sloty napojené na objekty sigc::signal běží ve vlákně, které volá na signál emit() nebo operator(). Glib::Dispatcher se takto nechová: místo toho jeho napojené sloty běží ve vlákně, ve kterém byl objekt Glib::Dispatcher vytvořen (které musí mít hlavní smyčku glib). Pokud je objekt Glib::Dispatcher vytvořen v hlavním vlákně grafického uživatelského rozhraní (který tedy bude mít přijímací vlákno), libovolné pracovním vlákno pro něj může vysílat a mít napojené sloty, které mohou bezpečně spouštět funkce gtkmm.

Některá bezpečnostní pravidla pro vlákna při použití Glib::Dispatcher stále platí. Jak bylo zmíněno, objekt Glib::Dispatcher musí být vytvořen ve vlákně příjemce (vlákno, ve kterém hlavní smyčka spustí jeho napojené sloty). Standardně je to hlavní vlákno programu, ačkoliv existuje konstruktor třídy Glib::Dispatcher, který umí převzít objekt Glib::MainContext libovolného vlákna, které má hlavní smyčku. Jen vlákno příjemce by mělo volat connect() na objekt Glib::Dispatcher, nebo manipulovat s souvisejícím objektem sigc::connection, pokud není zajištěna dodatečná synchronizace. Na druhou stranu, libovolné vlákno může bezpečně vyslat objekt Glib::Dispatcher bez zamykání, jakmile má vlákno příjemce napojené sloty, za předpokladu, že je vytvořen před spuštěním pracovního vlákna (jestliže je vytvořen po spuštění vlákna, je pro zajištění viditelnosti vyžadována dodatečná synchronizace).

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.