Threading in GTK [src]

GTK requires that the default GLib main context is iterated, in order for idles and timeouts to work (the GTK frame clock relies on this). This can be done in various ways: g_application_run(), g_main_loop_run() and g_main_context_iteration() are ways to do it.

The thread which iterates the main context is known as the main thread. In C applications, this is almost always the thread that runs main().

Threadsafe Objects

Objects may or may not be threadsafe - which means they are safe to be used (i.e. passed as arguments to functions) concurrently from multiple threads. Being threadsafe guarantees that all access to mutable state of the object is internally serialized.

Objects that are not threadsafe can only be used from one thread - the thread that they were created in.

Most GTK objects are not threadsafe and can only be used from the main thread, since they are all connected by references (all widgets are connected via the widget tree, and they all reference the display object).

Immutable Objects and Builders

A special class of threadsafe objects are immutable objects. These can safely be passed between threads and used in any thread.

Examples of immutable objects are

In connection with immutable objects, GTK frequently employs a builder pattern: A builder object collects all the data that is necessary to create an immutable object, and is discarded when the object is created. Builder objects can generally be used on any thread, as long as only one thread accesses it.

Examples of builders are

Patterns for Safe Use of Threads

Here are some recommendations for how to use threads in GTK applications in a safe way.

The first recommendation is to use async APIs for IO. GIO uses a thread pool to avoid blocking the main thread.

The second recommendation is to push long-running tasks to worker threads, and return the results back to the main thread via an idle or with g_main_context_invoke(). This can be achieved without manually juggling threads by using GTask or libdex.

A common scenario for the second recommendation is when the construction of an object has high overhead (e.g. creating GdkTexture may require loading and parsing a big image file). In this case, you may want to create the object in another thread, using a builder object there, and pass the immutable object back to the main thread after it has been created.

GTK provides some convenience API for this use case that is explicitly marked as threadsafe: - gdk_texture_new_from_resource() - gdk_texture_new_from_file() - gdk_texture_new_from_filename() - gdk_texture_new_from_bytes()