我正在尝试添加特定于特定GThread的超时源。
在主线程中,我可以创建一个GMainContext(g_main_context_new)并添加一个超时(g_timeout_add)。但是,当我尝试在用g_thread_create创建的线程中执行此操作时,它根本不起作用,GSourceFunc 从未被调用,我不知道为什么。
目前,我只有这个文档:
回调需要一点注意。来自 GTK+ 的回调(信号)在 GTK+ 锁内制作。但是来自 GLib 的回调(超时,IO 回调和空闲函数)是在 GTK+ 锁之外进行的。因此,在信号处理程序中,您无需调用gdk_threads_enter(),但在其他类型的回调中,您可以这样做。
但是我的超时函数(用于测试目的)仅在控制台中打印,因此我认为这不是资源保护和互斥锁的问题。
线程结构为:
主线程 --> 没有显式创建 GLib 主上下文
捕获线程
进程线程 --> 应该有一个 GLib 主上下文和一个超时源
显示线程
我感谢任何帮助。
提前谢谢。
你用g_timeout_add()
还是g_source_attach()
?
g_timeout_add()
和 g_timeout_add_full()
不允许指定要添加的主上下文。它始终使用默认的主上下文。如果您没有在主线程中使用默认的主上下文,则可以在process thread
中使用它。 您可以在说明中阅读有关它的信息。
GMainContext 只能在单个线程中运行
默认主上下文由许多函数隐式创建,包括 g_main_context_default()
。 因此,请确保您没有在主线程中使用它。
如果您决定这样做,可以使用 g_source_attach()
将超时源添加到您自己的主上下文中。没有可用于指定主上下文的超时函数。所以,你自己做吧。
以下代码与:g_timeout_add_full(G_PRIORITY_DEFAULT, 100, func, l, notify);
基本相同
#include <glib.h>
void notify(gpointer data)
{
g_main_loop_quit((GMainLoop *)data);
}
gboolean func(gpointer data)
{
static gint i = 0;
g_message("%d", i++);
return (i < 10) ? TRUE : FALSE;
}
gpointer thread(gpointer data)
{
GMainContext *c;
GMainContext *d;
GMainLoop *l;
GSource *s;
c = g_main_context_new();
d = g_main_context_default();
g_message("local: %p", c);
g_message("default: %p", d);
#if 1
l = g_main_loop_new(c, FALSE);
s = g_timeout_source_new(100);
g_source_set_callback(s, func, l, notify);
g_source_attach(s, c);
g_source_unref(s);
#else
l = g_main_loop_new(d, FALSE);
g_timeout_add_full(G_PRIORITY_DEFAULT, 100, func, l, notify);
#endif
g_main_loop_run(l);
g_message("done");
return NULL;
}
int main(int argc, char *argv[])
{
GError *error = NULL;
GThread *t;
g_thread_init(NULL);
t = g_thread_create(thread, NULL, TRUE, &error);
g_thread_join(t);
return 0;
}