Les utilisateurs de GLib sont-ils autorisés à exécuter plusieurs instances de GMainLoop
simultanément dans plusieurs threads, chaque thread exécutant sa propre instance? J’ai trouvé des réponses “oui” et “non” un peu partout. Je me rends compte que cette question a déjà été posée dans le cadre même de ce forum (décembre 2011) .
Cependant, je peux exécuter deux instances de GMainLoop
en même temps sans problème apparent. Mon code de test est très simple:
GMainLoop
dans main()
g_timeout_add
g_main_loop_run
g_main_context_new
g_main_context_push_thread_default
ce contexte comme thread par défaut à l’aide de g_main_context_push_thread_default
g_main_loop_new
et donnez-lui le nouveau contexte g_source_attach
la au nouveau contexte via g_source_attach
. g_main_loop_run
En faisant cela, je vois les deux instances de GMainLoop
fonctionner GMainLoop
. Les rappels de délai d’attente sont invoqués correctement et les appels ultérieurs à g_main_loop_quit fonctionnent comme prévu.
Il semble donc que le fait que plusieurs instances de GMainLoop
fonctionnent simultanément ne pose pas de problème. Mais peut-être n’ai-je pas suffisamment exercé l’API pour bien comprendre la situation. Y a-t-il une réponse définitive à cette question?
Aussi, voici le code de test réel si quelqu’un veut regarder:
#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); }
Le livre “Foundations of GTK + Development” dit ceci:
La boucle principale de GLib est implémentée sous la forme d’un certain nombre de structures qui permettent d’exécuter plusieurs instances simultanément.
Donc, compte tenu de cela, de mon code de test et du lien que j’ai posté dans le commentaire ci-dessus, nous avons une réponse définitive à cette question.
A savoir: plusieurs threads peuvent avoir leur propre GMainContext & GMainLoop, et sont capables d’exécuter ces boucles indépendamment de manière concurrente.