add callback for separate g_main_loop

前端 未结 1 906
野性不改
野性不改 2021-01-18 17:56

I have some misunderstanding about how GMainLoop work. Main thing - API which add some callbacks into g_main_loop (like g_timeout_add_seconds

相关标签:
1条回答
  • 2021-01-18 18:36

    A quick look at the documentation for g_idle_add(), g_idle_add_full(), g_timeout_add(), or g_timeout_add_full() will tell you:

    This internally creates a main loop source using g_timeout_source_new() and attaches it to the main loop context using g_source_attach(). You can do these steps manually if you need greater control.

    Note that it says it attaches the source to the main loop contexti.e., a GMainContext, not a GMainLoop. When you create your GMainLoop instances you're passing NULL for the first argument. According to the the g_main_loop_new() documentation, that argument is

    a GMainContext (if NULL, the default context will be used).

    So, you are creating two main loops, both using the same context (which is the default context).

    To get the result I think you're expecting, you should do something like:

    #include <glib.h>
    
    gboolean callback(gpointer data)
    {
      static guint16 i=0; 
      g_print("Iter=%"G_GUINT16_FORMAT"\n",i++);
      if(i%5==0){
        g_print("try to stop loop1\n", data);
        g_main_loop_quit((GMainLoop*)data);
      }
      return TRUE;
    }
    
    int main()
    {
      GMainContext* con1 = NULL;
      GMainContext* con2 = NULL;
      GMainLoop* loop1 = NULL;
      GMainLoop* loop2 = NULL;
      GSource* source1 = NULL;
    
      con1 = g_main_context_new ();
      con2 = g_main_context_new ();
    
      loop1 = g_main_loop_new (con1, FALSE);
      loop2 = g_main_loop_new (con2, FALSE);
    
      source1 = g_timeout_source_new_seconds (1);
      g_source_set_callback (source1, callback, loop1, NULL);
      g_source_attach (source1, con1);
    
      // We don't need the GMainContext anymore—the loop has an internal
      // reference so we'll drop ours.
      g_main_context_unref (con1);
      con1 = NULL;
    
      // Ditto for the GSource
      g_source_unref (source1);
      source1 = NULL;
    
      g_main_context_unref (con2);
      con2 = NULL;
    
      g_print("run loop1\n");
      g_main_loop_run(loop1);
      // Use g_main_loop_unref, not g_free
      g_main_loop_unref(loop1);
      loop1 = NULL;
    
      g_print("run loop2\n");
      // Note that there is no longer a callback attached here, so it will
      // run forever.
      g_main_loop_run(loop2);
      g_main_loop_unref(loop2);
      loop2 = NULL;
    
      return 0;
    }
    
    0 讨论(0)
提交回复
热议问题