Glib:调用迭代循环函数



查询超时调用和GMainContext。这真的让我很困惑

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

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

  • 一个启动循环函数
  • 另一个结束循环函数

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

  • 创建另一个超时
  • 使用相同的方法创建check_cmd

基本上,当我尝试这两种方法时,两者对我来说几乎都是相同的方法。计划A(正如我所说的)不起作用,但计划B......实际上至少运行一次。所以我想知道如何解决它们...

或者也许我应该使用 g_source_add_child_source() 代替?

总之,我的问题是

  • 当您创建一个新上下文并将其推送为默认上下文时,是否需要main_context的所有后续函数都会引用此上下文?
  • 简而言之,当循环已经运行时,您如何添加新源,即像我的情况一样
  • 最后,可以在您创建的回调中退出主循环吗?

这是我的伪代码

#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 successfullyn");
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;
}

总之,我的问题是

  1. 当您创建一个新上下文并将其推送为默认上下文时,请执行所有需要main_context Will 的后续函数 参考此上下文?

记录为使用线程默认主上下文的函数将使用最近通过g_main_context_push_thread_default()推送的GMainContext

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

g_timeout_add_seconds()记录为使用全局默认主上下文。因此,如果您希望将超时源附加到特定GMainContext,则需要使用计划 B。

    简而言之,
  1. 当循环已经运行时,您如何添加新源,即像我的情况一样

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

  1. 最后,可以在您创建的回调中退出主循环吗?

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

从您的代码来看,您似乎没有为每个GMainContext创建一个新GMainLoop,而是假设一个GMainLoop将以某种方式处理该过程中的所有GMainContext。这是不正确的。如果要使用GMainLoop,则需要为创建的每个GMainContext创建一个新。


撇开所有其他事情不谈,你可能会发现使用 GLib 的线程函数比直接使用 pthread 更容易。GLib的线程函数可以移植到其他平台,并且更容易使用。鉴于您已经链接到libglib,使用它们不会花费任何额外费用。

相关内容

  • 没有找到相关文章

最新更新