Running multiple concurrent GMainLoops

GMainLoop GLib users allowed to run multiple instances of GMainLoop simultaneously in multiple threads, with each thread starting its own instance? I found yes and no answers everywhere. I understand that this question was asked earlier in this forum (December 2011) .

However, I can run two instances of GMainLoop at the same time without an obvious problem. My test code is very simple:

  • Create GMainLoop in main()
  • Create a timeout source for the default context and main loop with g_timeout_add
  • Create GThread in main ()
  • Run the main loop using g_main_loop_run
  • [THREADING CONTEXT]: create a context using g_main_context_new
  • [THREAD CONTEXT]: set this context as the default thread using g_main_context_push_thread_default
  • [THREAD CONTEXT]: create a loop with g_main_loop_new and give it a new context
  • [THREAD CONTEXT]: Create a timeout source and add it to the new context via g_source_attach .
  • [THREAD_CONTEXT]: call the stream g_main_loop_run

By doing this, I see that both instances of GMainLoop are working fine. Timeout response requests are called correctly, and then g_main_loop_quit calls work as expected.

So it looks like there aren't many concurrent GMainLoop instances. But maybe I just did not use the API enough to fully understand the situation. Is there a definitive answer to this question?

In addition, here is a real test code, if someone needs to look:

 #define THREAD_TIMEOUTS (20) #define MAIN_TIMEOUS (1) typedef struct timeout_struct { int i; int max; GMainLoop *loop; char *name; } TIMEOUT_STRUCT; gboolean timeout_callback(gpointer data) { TIMEOUT_STRUCT *psTimeout = (TIMEOUT_STRUCT *)data; psTimeout->i++; if (psTimeout->i == psTimeout->max) { if (psTimeout->max == THREAD_TIMEOUTS) { g_main_loop_quit( (GMainLoop*)psTimeout->loop ); } return FALSE; } return TRUE; } void* thread_function(void *data) { GMainContext *ps_context; GMainLoop *ps_loop; GSource *ps_timer; TIMEOUT_STRUCT sTimeout; ps_context = g_main_context_new(); g_main_context_push_thread_default(ps_context); ps_loop = g_main_loop_new(ps_context, FALSE); sTimeout.i = 0; sTimeout.max = THREAD_TIMEOUTS; sTimeout.loop = ps_loop; sTimeout.name = "thread"; ps_timer = g_timeout_source_new_seconds(1); g_source_set_callback(ps_timer, timeout_callback, &sTimeout, NULL); g_source_attach(ps_timer, ps_context); g_main_loop_run(ps_loop); g_main_loop_quit( (GMainLoop*)data ); return NULL; } /* * This main boots a thread, then starts up a GMainLoop. Then the thread runs * a GMainLoop. The thread sets a timer that fires ten times and the main sets a * timer that fires two times. The thread quits and * and then the other main l * * * */ int main() { GThread *ps_thread; GMainLoop *loop; TIMEOUT_STRUCT sTimeout; loop = g_main_loop_new ( NULL , FALSE ); sTimeout.i = 0; sTimeout.max = MAIN_TIMEOUS; sTimeout.loop = loop; sTimeout.name = "main"; // add source to default context g_timeout_add (1 , timeout_callback, &sTimeout); ps_thread = g_thread_new("thread", thread_function, loop); g_main_loop_run (loop); g_main_loop_unref(loop); } 
+7
c multithreading glib
source share
1 answer

The book GTK Fundamentals + Development says the following:

The main GLib loop is implemented as multiple structures that allow multiple instances to run simultaneously.

So, given this, my test code and the link posted in the comments above, we have the final answer to this question.

Namely: several threads can have their own GMainContext and GMainLoop and can independently run these cycles simultaneously.

+9
source share

All Articles