Are users of GLib allowed to run multiple GMainLoop
instances concurrently in multiple threads, with each thread running its own instance? I've found "yes" and "no" answers all over the place. I realize that this question has been asked before in this very forum (December 2011).
However, I am able to run two GMainLoop
instances at the same time without apparent issue. My test code is very simple:
GMainLoop
in main()
g_timeout_add
g_main_loop_run
g_main_context_new
g_main_context_push_thread_default
g_main_loop_new
and give it the new context g_source_attach
. g_main_loop_run
Doing this, I see both instances of the GMainLoop
working just fine. The timeout callbacks are invoked correctly, and later calls to g_main_loop_quit work as expected.
So, it looks like it is not a problem to have multiple GMainLoop
instances working concurrently. But perhaps I just haven't exercised the API enough to fully grasp the situation. Is there a definitive answer to this question?
Also, here's the actual test code if anybody cares 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);
}
The book "Foundations of GTK+ Development" states this:
The GLib main loop is implemented as a number of structures, which allow multiple instances to be run concurrently.
So, given this, my test code, and the link I posted in the comment above we have a definitive answer to this question.
Namely: Multiple threads may have their own GMainContext & GMainLoop, and are able to independently run these loops in a concurrent fashion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With