查询超时调用和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;
}
总之,我的问题是
- 当您创建一个新上下文并将其推送为默认上下文时,请执行所有需要main_context Will 的后续函数 参考此上下文?
记录为使用线程默认主上下文的函数将使用最近通过g_main_context_push_thread_default()
推送的GMainContext
。
记录为使用全局默认主上下文的函数不会。他们将使用在 init 时创建并与主线程关联的GMainContext
。
g_timeout_add_seconds()
记录为使用全局默认主上下文。因此,如果您希望将超时源附加到特定GMainContext
,则需要使用计划 B。
简而言之,
- 当循环已经运行时,您如何添加新源,即像我的情况一样
g_source_attach()
在迭代主上下文时起作用。
- 最后,可以在您创建的回调中退出主循环吗?
是的,g_main_loop_quit()
可以随时调用。
从您的代码来看,您似乎没有为每个GMainContext
创建一个新GMainLoop
,而是假设一个GMainLoop
将以某种方式处理该过程中的所有GMainContext
。这是不正确的。如果要使用GMainLoop
,则需要为创建的每个GMainContext
创建一个新。
撇开所有其他事情不谈,你可能会发现使用 GLib 的线程函数比直接使用 pthread 更容易。GLib的线程函数可以移植到其他平台,并且更容易使用。鉴于您已经链接到libglib,使用它们不会花费任何额外费用。