Exécution simultanée de plusieurs GMainLoops

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:

  1. Créer un GMainLoop dans main()
  2. Créez une source de délai d’attente pour le contexte par défaut et la boucle principale à l’aide de g_timeout_add
  3. Créer un GThread dans main ()
  4. Exécutez la boucle principale en utilisant g_main_loop_run
  5. [THREAD CONTEXT]: Créer un contexte en utilisant g_main_context_new
  6. [THREAD CONTEXT]: g_main_context_push_thread_default ce contexte comme thread par défaut à l’aide de g_main_context_push_thread_default
  7. [THREAD CONTEXT]: Créez une boucle en utilisant g_main_loop_new et donnez-lui le nouveau contexte
  8. [THREAD CONTEXT]: Créez une source de délai d’expiration et g_source_attach la au nouveau contexte via g_source_attach .
  9. [THREAD_CONTEXT]: le thread 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.