为单独的g_main_loop添加回调 [英] add callback for separate 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 usingg_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 context—i.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
(ifNULL
, 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屋!