【发布时间】:2014-01-31 16:55:29
【问题描述】:
是否允许 GLib 的用户在多个线程中同时运行多个 GMainLoop 实例,每个线程运行自己的实例?我到处都找到了“是”和“否”的答案。我意识到这个问题之前已经在这个论坛(December 2011) 上提出过。
但是,我可以同时运行两个 GMainLoop 实例而不会出现明显问题。我的测试代码很简单:
- 在
main()中创建一个GMainLoop - 使用
g_timeout_add为默认上下文和主循环创建超时源 - 在 main() 中创建一个 GThread
- 使用
g_main_loop_run运行主循环 - [线程上下文]:使用
g_main_context_new创建上下文 - [线程上下文]:使用
g_main_context_push_thread_default将该上下文设置为线程默认值 - [THREAD CONTEXT]:使用
g_main_loop_new创建一个循环并为其赋予新的上下文 - [线程上下文]:创建超时源,并通过
g_source_attach将其附加到新上下文。 - [THREAD_CONTEXT]:让线程调用
g_main_loop_run
这样做,我看到GMainLoop 的两个实例都工作得很好。超时回调被正确调用,随后对 g_main_loop_quit 的调用按预期工作。
因此,让多个GMainLoop 实例同时工作似乎不是问题。但也许我只是没有充分运用 API 来完全掌握情况。这个问题有确定的答案吗?
另外,如果有人愿意看,这里是实际的测试代码:
#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);
}
【问题讨论】:
-
我刚刚发现this 似乎同意这是可接受的 GLib API 用法。所以,我猜“是的,这很好”列中的另一个条目。
标签: c multithreading glib