运行多个并发GMainLoops [英] Running multiple concurrent GMainLoops

查看:1095
本文介绍了运行多个并发GMainLoops的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

GLib的是用户允许在多个线程同时运行多个 GMainLoop 实例,而每个线程中运行自己的实例?我发现是和否的回答所有的地方。我意识到,这个问题已经在这个论坛问过(2011年12月)

不过,我能没有明显的问题,运行在同一时间两个 GMainLoop 实例。我的测试code是非常简单的:


  1. 创建一个 GMainLoop 的main()

  2. 创建默认情况下超时来源和使用主循环 g_timeout_add

  3. 创建在main()
  4. 系统GThread
  5. 使用运行主循环 g_main_loop_run

  6. [线程上下文]:创建使用上下文 g_main_context_new

  7. [线程上下文]:设置上下文使用线程默认 g_main_context_push_thread_default

  8. [线程上下文]:创建一个使用 g_main_loop_new 一个循环,并赋予它新的上下文

  9. [线程上下文]:创建一个超时来源,它通过 g_source_attach 附加到新环境。

  10. [THREAD_CONTEXT]:有线程调用 g_main_loop_run

这样做,我看到的工作就好了 GMainLoop 的两个实例。超时回调被正确调用,后来调用按预期g_main_loop_quit的工作。

所以,它看起来是不是有并发工作的多个 GMainLoop 实例的问题。但也许我只是还没有行使API不够充分掌握情况。是否有一个明确的答案?

此外,这里的实际测试code,如果有人关心一下:

 的#define THREAD_TIMEOUTS(20)
的#define MAIN_TIMEOUS(1)typedef结构timeout_struct
{
    INT I;
    INT最大;
    GMainLoop *循环;
    字符*名称;} TIMEOUT_STRUCT;gboolean timeout_callback(gpointer数据)
{
    TIMEOUT_STRUCT * psTimeout =(TIMEOUT_STRUCT *)的数据;    psTimeout- I标记++;    如果(psTimeout- I标记== psTimeout->最大)
    {
        如果(psTimeout->最大== THREAD_TIMEOUTS)
        {
            g_main_loop_quit((GMainLoop *)psTimeout->环);
        }
        返回FALSE;
    }    返回TRUE;
}
无效* thread_function(void *的数据)
{
    GMainContext * ps_context;
    GMainLoop * ps_loop;
    GSource * ps_timer;
    TIMEOUT_STRUCT sTimeout;    ps_context = g_main_context_new();
    g_main_context_push_thread_default(ps_context);    ps_loop = g_main_loop_new(ps_context,FALSE);    sTimeout.i = 0;
    sTimeout.max = THREAD_TIMEOUTS;
    sTimeout.loop = ps_loop;
    sTimeout.name =线程;
    ps_timer = g_timeout_source_new_seconds(1);
    g_source_set_callback(ps_timer,timeout_callback,&放大器; sTimeout,NULL);
    g_source_attach(ps_timer,ps_context);    g_main_loop_run(ps_loop);    g_main_loop_quit((GMainLoop *)的数据);    返回NULL;}
/ *
 *这个主引导一个线程,然后启动了GMainLoop。然后线程运行
 *一个GMainLoop。线程设置一个触发十倍和主集的计时器
 *计时器触发两次。线程退出,
 *然后其他主升
 *
 *
 * * /
诠释的main()
{
    GThread * ps_thread;
    GMainLoop *循环;
    TIMEOUT_STRUCT sTimeout;    循环= g_main_loop_new(NULL,FALSE);    sTimeout.i = 0;
    sTimeout.max = MAIN_TIMEOUS;
    sTimeout.loop =环路;
    sTimeout.name =主;    //添加源到默认的上下文
    g_timeout_add(1,timeout_callback,&放大器; sTimeout);    ps_thread = g_thread_new(线程,thread_function,循环);    g_main_loop_run(环);
    g_main_loop_unref(环);
}


解决方案

这本书GTK +开发的基础这一状态:


  

油嘴主循环被实施为许多结构,其允许多个实例
  同期执行。


因此​​,考虑到这一点,我的测试code,以及链接我在评论上面贴我们有一个明确的回答这个问题。

即:多个线程可以有自己的GMainContext&安培; GMainLoop,并能够在并行的方式独立地运行这些环路。

Are users of GLib allowed to run multiple GMainLoop instances concurrently in multiple threads, with each thread running its own instance? I've found "yes" and "no" answers all over the place. I realize that this question has been asked before in this very forum (December 2011).

However, I am able to run two GMainLoop instances at the same time without apparent issue. My test code is very simple:

  1. Create a GMainLoop in main()
  2. Create a timeout source for the default context and the main loop using g_timeout_add
  3. Create a GThread in main()
  4. Run the main loop using g_main_loop_run
  5. [THREAD CONTEXT]: Create a context using g_main_context_new
  6. [THREAD CONTEXT]: Set that context as the thread default using g_main_context_push_thread_default
  7. [THREAD CONTEXT]: Create a loop using g_main_loop_new and give it the new context
  8. [THREAD CONTEXT]: Create a timeout source, and attach it to the new context via g_source_attach.
  9. [THREAD_CONTEXT]: Have the thread invoke g_main_loop_run

Doing this, I see both instances of the GMainLoop working just fine. The timeout callbacks are invoked correctly, and later calls to g_main_loop_quit work as expected.

So, it looks like it is not a problem to have multiple GMainLoop instances working concurrently. But perhaps I just haven't exercised the API enough to fully grasp the situation. Is there a definitive answer to this question?

Also, here's the actual test code if anybody cares to look:

#define THREAD_TIMEOUTS (20)
#define MAIN_TIMEOUS (1)

typedef struct timeout_struct
{
    int i;
    int max;
    GMainLoop *loop;
    char *name;

} TIMEOUT_STRUCT;

gboolean timeout_callback(gpointer data)
{
    TIMEOUT_STRUCT *psTimeout = (TIMEOUT_STRUCT *)data;

    psTimeout->i++;

    if (psTimeout->i == psTimeout->max)
    {
        if (psTimeout->max == THREAD_TIMEOUTS)
        {
            g_main_loop_quit( (GMainLoop*)psTimeout->loop );
        }
        return FALSE;
    }

    return TRUE;
}
void* thread_function(void *data)
{
    GMainContext *ps_context;
    GMainLoop *ps_loop;
    GSource *ps_timer;
    TIMEOUT_STRUCT sTimeout;

    ps_context = g_main_context_new();
    g_main_context_push_thread_default(ps_context);

    ps_loop = g_main_loop_new(ps_context, FALSE);

    sTimeout.i = 0;
    sTimeout.max = THREAD_TIMEOUTS;
    sTimeout.loop = ps_loop;
    sTimeout.name = "thread";
    ps_timer = g_timeout_source_new_seconds(1);
    g_source_set_callback(ps_timer, timeout_callback, &sTimeout, NULL);
    g_source_attach(ps_timer, ps_context);

    g_main_loop_run(ps_loop);

    g_main_loop_quit( (GMainLoop*)data );

    return NULL;

}
/*
 * This main boots a thread, then starts up a GMainLoop.  Then the thread runs
 * a GMainLoop.  The thread sets a timer that fires ten times and the main sets a
 * timer that fires two times. The thread quits and
 * and then the other main l
 *
 *
 * */
int main()
{
    GThread *ps_thread;
    GMainLoop *loop;
    TIMEOUT_STRUCT sTimeout;

    loop = g_main_loop_new ( NULL , FALSE );

    sTimeout.i = 0;
    sTimeout.max = MAIN_TIMEOUS;
    sTimeout.loop = loop;
    sTimeout.name = "main";

    // add source to default context
    g_timeout_add (1 , timeout_callback, &sTimeout);

    ps_thread = g_thread_new("thread", thread_function, loop);

    g_main_loop_run (loop);
    g_main_loop_unref(loop);
}

解决方案

The book "Foundations of GTK+ Development" states this:

The GLib main loop is implemented as a number of structures, which allow multiple instances to be run concurrently.

So, given this, my test code, and the link I posted in the comment above we have a definitive answer to this question.

Namely: Multiple threads may have their own GMainContext & GMainLoop, and are able to independently run these loops in a concurrent fashion.

这篇关于运行多个并发GMainLoops的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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