Glib:调用迭代循环函数
Glib: Calling a iterative loop function
查询超时调用和GMainContext。真是让我一头雾水
假设我有下面的代码(有点不完整,只是为了演示)。我使用普通的 Pthreads 创建线程。在线程中,我 运行 Glib 功能并创建了一个 GMainContext(存储在 l_app.context 中)。
然后我以大约 1 秒的间隔迭代地为 运行 函数 check_cmd 创建了一个源代码。这个回调(或者我们可以称它为线程吗?)将检查来自其他线程的命令(此处未显示用于更新 cmd 状态的 Pthreads)。从这里开始,有两个特定的命令
- 一个启动循环函数
- 另一个结束循环的函数
我已经完成并想到了两种方法来创建函数并将它们迭代设置为 运行。
- 创建另一个超时
- 使用相同的方法创建check_cmd
当我尝试这两种方法时,对我来说基本上都是相同的方法。计划 A(我这样称呼它)行不通,但计划 B ......实际上 运行 至少一次。所以我想知道如何修复它们...
或者我应该改用 g_source_add_child_source()?
总而言之,我的问题是
- 当您创建一个新的上下文并将其推送为默认上下文时,所有需要 main_context 的后续函数都将引用此上下文吗?
- 简而言之 shell,当循环已经 运行ning 时如何添加新源,即像我的案例
- 最后,可以在您创建的回调中退出主循环吗?
这是我的伪代码
#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
- 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
- in a nut shell, how do you add new sources when a loop is already running, ie like my cases
g_source_attach()
在迭代主上下文时起作用。
- 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,使用它们不需要额外费用。
查询超时调用和GMainContext。真是让我一头雾水
假设我有下面的代码(有点不完整,只是为了演示)。我使用普通的 Pthreads 创建线程。在线程中,我 运行 Glib 功能并创建了一个 GMainContext(存储在 l_app.context 中)。
然后我以大约 1 秒的间隔迭代地为 运行 函数 check_cmd 创建了一个源代码。这个回调(或者我们可以称它为线程吗?)将检查来自其他线程的命令(此处未显示用于更新 cmd 状态的 Pthreads)。从这里开始,有两个特定的命令
- 一个启动循环函数
- 另一个结束循环的函数
我已经完成并想到了两种方法来创建函数并将它们迭代设置为 运行。
- 创建另一个超时
- 使用相同的方法创建check_cmd
当我尝试这两种方法时,对我来说基本上都是相同的方法。计划 A(我这样称呼它)行不通,但计划 B ......实际上 运行 至少一次。所以我想知道如何修复它们...
或者我应该改用 g_source_add_child_source()?
总而言之,我的问题是
- 当您创建一个新的上下文并将其推送为默认上下文时,所有需要 main_context 的后续函数都将引用此上下文吗?
- 简而言之 shell,当循环已经 运行ning 时如何添加新源,即像我的案例
- 最后,可以在您创建的回调中退出主循环吗?
这是我的伪代码
#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
- 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
.
- in a nut shell, how do you add new sources when a loop is already running, ie like my cases
g_source_attach()
在迭代主上下文时起作用。
- 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,使用它们不需要额外费用。