Glib:调用迭代循环函数

Glib: Calling a iterative loop function

查询超时调用和GMainContext。真是让我一头雾水

假设我有下面的代码(有点不完整,只是为了演示)。我使用普通的 Pthreads 创建线程。在线程中,我 运行 Glib 功能并创建了一个 GMainContext(存储在 l_app.context 中)。

然后我以大约 1 秒的间隔迭代地为 运行 函数 check_cmd 创建了一个源代码。这个回调(或者我们可以称它为线程吗?)将检查来自其他线程的命令(此处未显示用于更新 cmd 状态的 Pthreads)。从这里开始,有两个特定的命令

我已经完成并想到了两种方法来创建函数并将它们迭代设置为 运行。

当我尝试这两种方法时,对我来说基本上都是相同的方法。计划 A(我这样称呼它)行不通,但计划 B ......实际上 运行 至少一次。所以我想知道如何修复它们...

或者我应该改用 g_source_add_child_source()?

总而言之,我的问题是

这是我的伪代码

#include <glib.h>
#include <dirent.h>
#include <errno.h>

#include <pthread.h>

#define PLAN_A             0

typedef struct
 {
    GMainContext *context;
    GMainLoop *loop;
 }_App;


static _App l_app;
guint gID;

gboolean
time_cycle(gpointer udata)
{
    g_print("I AM THREADING");
    return true;
}

gboolean
check_cmd_session(NULL )
{
    while(alive)           /// alive is a boolean value that is shared with other threads(not shown)                     
    { 

        if(start)
        {
        /// PLAN A
        //// which context does this add to ??
#if PLAN_A
             g_timeout_add_seconds(10, (GSourceFunc)timeout, NULL);
#else
            /// or should i use PLAN B
            GSource* source = g_timeout_source_new(1000);

            gID = g_source_set_callback(source,
                            (GSourceFunc)time_cycle,
                            NULL,
                            NULL);

            g_source_attach(source, l_app.context);
#endif
        }
        else
        {
#if PLAN_A
            g_source_remove(gID);
#else           
        }

    }

    g_main_loop_quit (l_app.loop);
    return FALSE;
}



void*
liveService(Info *info)
{

    l_app.context = g_main_context_new ();
    g_main_context_push_thread_default(l_app.context);


    GSource* source = g_timeout_source_new(1000);

    g_source_set_callback(source,
                          (GSourceFunc)check_cmd_session,
                          NULL,
                          NULL);

    /// make it run
    g_source_attach(source, l_app.context);
    

    g_main_loop_run (l_app.loop);

    pthread_exit(NULL);

}



int main()
{
    pthread_t tid[2];

    int thread_counter = 0;
    err = pthread_create(&(tid[thread_counter]), NULL, &live, &info);
    if (err != 0)
    {
        printf("\n can't create live thread :[%s]", strerror(err));
    }
    else
    {
        printf("--> Thread for Live created successfully\n");
        thread_counter++;
    }


    /**** other threads are build not shown here */

    for(int i = 0; i < 2; i++)
    {
        printf("Joining the %d threads \n", i);
        pthread_join(tid[i],NULL);
    }

    return 0;

}

In Summary, my question is

  1. when you created a new context and push it to become the default context, do all subsequent function that require main_context will refer to this context?

记录为使用 thread-default 主上下文的函数将使用最近使用 g_main_context_push_thread_default() 推送的 GMainContext

记录为使用 global 默认主上下文的函数不会。他们将使用在初始化时创建并与主线程关联的 GMainContext

g_timeout_add_seconds() 被记录为使用 global 默认主上下文。因此,如果您希望将超时源附加到特定的 GMainContext.

,则需要使用计划 B
  1. in a nut shell, how do you add new sources when a loop is already running, ie like my cases

g_source_attach() 在迭代主上下文时起作用。

  1. lastly, it is okay to quit the main loop within the callback you have created?

是的,g_main_loop_quit()可以随时调用。

从你的代码来看,你似乎没有为每个 GMainContext 创建一个新的 GMainLoop,而是假设一个 GMainLoop 将以某种方式与所有 [=10] 一起工作=]s 在这个过程中。那是不正确的。如果您要使用 GMainLoop,您需要为每个 GMainContext 创建一个新的。


抛开所有其他因素,您可能会发现使用 GLib 的线程函数比直接使用 pthread 更容易。 GLib 的线程函数可移植到其他平台并且更易于使用。鉴于您已经链接到 libglib,使用它们不需要额外费用。