为单独的g_main_loop添加回调 [英] add callback for separate g_main_loop

查看:207
本文介绍了为单独的g_main_loop添加回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对GMainLoop的工作方式有一些误解. 主要内容-向g_main_loop中添加一些回调(例如g_timeout_add_seconds())的API不会使用指向要添加该回调的循环的指针.

I have some misunderstanding about how GMainLoop work. Main thing - API which add some callbacks into g_main_loop (like g_timeout_add_seconds()) don't take pointer to which loop you want to add that callback.

似乎您为所有g_main_loop实例添加了回调. 即使您尚未创建.一个简单的例子:

It looks like you add callback's for all g_main_loop instances. Even if you have not yet created. Simple example for this:

#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");
    g_main_loop_quit((GMainLoop*)data);
  }
  return TRUE;
}

int main()
{
  GMainLoop* loop1 = NULL;
  GMainLoop* loop2 = NULL;
  loop1 = g_main_loop_new (NULL, FALSE);

  g_timeout_add_seconds(1, callback,loop1);

  loop2 = g_main_loop_new (NULL, FALSE);
  g_print("run loop1\n");
  g_main_loop_run(loop1);
  g_free(loop1);
  g_print("run loop2\n");
  g_main_loop_run(loop2);
  g_free(loop2);
  return 0;
}

结果是:

run loop1
Iter=0
Iter=1
Iter=2
Iter=3
Iter=4
try to stop loop1
run loop2
Iter=5
Iter=6
Iter=7
Iter=8
Iter=9
try to stop loop1
Segmentation fault (core dumped)

是否可以将callback()添加到loop1,而不将其添加到loop2?

Is it possible add callback() to loop1, and don't add it to loop2?

推荐答案

快速浏览 g_idle_add_full() g_timeout_add_full() 会告诉您:

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:

这在内部使用 g_timeout_source_new() 并使用

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.

请注意,它表示将源附加到主循环 context - ie ,即 GMainLoop .创建GMainLoop实例时,您要为第一个参数传递NULL.根据 the g_main_loop_new() documentation ,该参数是

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 (如果NULL ,将使用默认上下文).

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;
}

这篇关于为单独的g_main_loop添加回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆