GThread中的g_timeout_add [英] g_timeout_add inside a GThread

查看:213
本文介绍了GThread中的g_timeout_add的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试添加特定于特定GThread的超时源.

I'm trying to add a timeout source specific to a particular GThread.

在主线程中,我可以创建一个GMainContext( g_main_context_new )并添加一个超时( g_timeout_add ).但是,当我尝试在使用 g_thread_create 创建的线程中执行此操作时,它根本无法正常工作,因此从不调用GSourceFunc,也不知道为什么.

In the main thread, I can create a GMainContext (g_main_context_new) and add a timeout (g_timeout_add). However, when I try to do it in a thread created with g_thread_create it simply doesn't work, the GSourceFunc is never called and I have no clue why.

目前,我仅获得此文档:

For the moment I've only got this the documentation:

回调需要引起注意.来自GTK +的回调(信号) 是在GTK +锁内进行的.但是,来自GLib的回调(超时, IO回调和空闲函数)是在GTK +锁之外进行的. 因此,在信号处理程序中,您无需调用 gdk_threads_enter(),但在其他类型的回调中,您可以这样做.

Callbacks require a bit of attention. Callbacks from GTK+ (signals) are made within the GTK+ lock. However callbacks from GLib (timeouts, IO callbacks, and idle functions) are made outside of the GTK+ lock. So, within a signal handler you do not need to call gdk_threads_enter(), but within the other types of callbacks, you do.

但是我的超时功能(出于测试目的)仅在控制台中打印,因此我认为这不是资源保护和互斥锁的问题.

But my timeout function (for testing purposes) only prints in the console, so I don't think it's a problem of resource protection and mutexes.

线程结构为:

主线程->没有明确创建GLib主上下文

Main thread --> no GLib main context explicitly created

  • 捕获线程

  • capture thread

进程线程->应该具有GLib主上下文和超时源

process thread --> should have a GLib main context and a timeout source

显示线程

感谢您的帮助.

谢谢.

推荐答案

您使用g_timeout_add()还是g_source_attach()?

g_timeout_add()g_timeout_add_full()不允许您指定要添加的主要上下文.它始终使用默认的主上下文.如果您没有在主线程中使用默认的主上下文,则可以在process thread中使用它.您可以在说明.

g_timeout_add() and g_timeout_add_full() does not allow you to specify which main context to add. It always use the default main context. if you are not using the default main context in your main thread, it is perfectly ok to use it in your process thread. You can read about it in the description.

GMainContext只能在单个线程中运行

A GMainContext can only be running in a single thread

默认主上下文是由许多功能(包括g_main_context_default())隐式创建的.因此,请确保您没有在主线程中使用它.

The default main context is implicitly created by many functions, including g_main_context_default(). So please make sure that you have not using it in your main thread.

如果决定这样做,则可以使用g_source_attach()将超时源添加到自己的主上下文中.没有可以用于指定主上下文的超时功能.因此,只需自己动手做即可.

You can use g_source_attach() to add a timeout source to your own main context if you decided to do so. There is no timeout function you can use to specify your main context. So, just do it by your self.

以下代码与以下代码基本相同:g_timeout_add_full(G_PRIORITY_DEFAULT, 100, func, l, notify);

The following code is basically same as: 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;
}

这篇关于GThread中的g_timeout_add的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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