GLib的GMainContext在一个线程?(GLib GMainContext in a thr

2019-09-29 20:57发布

我已经搜查堆栈溢出找到有关我的问题的答案。 但我没有找到任何答案。

我有一个启动一个线程主线程(我的main()函数)。 新的线程运行GMainLoop。 在我的主要功能,我一直通过调用添加源g_io_watch在一些文件描述符。 但我已经越来越垃圾的数据,如果事件被分派。

下面是我努力的代码的一小部分:

GMainLoop *loop;

gpointer event_loop_thread(gpointer arg)
{   
    g_main_loop_run(loop);
    g_main_loop_unref(loop);
    return NULL;
}

int init()
{
    loop = g_main_loop_new(NULL, FALSE);
    g_thread_new(NULL, event_loop_thread, NULL);
    return 0;
}

gboolean __hci_service(GIOChannel *source, GIOCondition condition, gpointer data)
{
    // Doing something
    return FALSE;
}

int main()
{
    init();
    int _adapter_id = hci_devid("hci0");
    int hci_dev = hci_open_dev(_adapter_id);
    GIOChannel *p_hci_io = g_io_channel_unix_new(dev_id);

    GIOCondition cond = (GIOCondition)(G_IO_IN);
    g_io_add_watch(p_hci_io, cond, __hci_service, NULL);

    while (true);
    // I will close file descriptor
    return 0;

}

但是,如果我尝试这个代码,然后一切按预期工作:

GMainLoop *loop;

gpointer event_loop_thread(gpointer arg)
{   
    g_main_loop_run(loop);
    g_main_loop_unref(loop);
    return NULL;
}

int init()
{
    loop = g_main_loop_new(NULL, FALSE);
    g_thread_new(NULL, event_loop_thread, NULL);
    return 0;
}

gboolean __hci_service(GIOChannel *source, GIOCondition condition, gpointer data)
{
    // Doing something
    return FALSE;
}

int main()
{
    // init();
    int _adapter_id = hci_devid("hci0");
    int hci_dev = hci_open_dev(_adapter_id);
    GIOChannel *p_hci_io = g_io_channel_unix_new(dev_id);

    GIOCondition cond = (GIOCondition)(G_IO_IN);
    g_io_add_watch(p_hci_io, cond, __hci_service, NULL);

    loop = g_main_loop_new(NULL, FALSE);
    g_main_loop_run(loop);
    g_main_loop_unref(loop);

    while (true);
    // I will close file descriptor
    return 0;

} 

编辑:

我曾尝试通过将默认GMainContext主线程的新创建的线程。 看一看。 告诉我,如果我的做法是正确的。

GMainLoop *loop;

gpointer event_loop_thread(gpointer arg)
{   
    GMainContext *context = (GMainContext *)arg;
    loop = g_main_loop_new(context, FALSE);
    g_main_context_push_thread_default(context);
    g_main_loop_run(loop);
    g_main_loop_unref(loop);
    return NULL;
}

int init()
{

    g_thread_new(NULL, event_loop_thread, (gpointer)g_main_context_default());
    return 0;
}

gboolean __hci_service(GIOChannel *source, GIOCondition condition, gpointer data)
{
    // Doing something
    return FALSE;
}

int main()
{
    init();
    int _adapter_id = hci_devid("hci0");
    int hci_dev = hci_open_dev(_adapter_id);
    GIOChannel *p_hci_io = g_io_channel_unix_new(dev_id);

    GIOCondition cond = (GIOCondition)(G_IO_IN);
    g_io_add_watch(p_hci_io, cond, __hci_service, NULL);

    //loop = g_main_loop_new(NULL, FALSE);
    //g_main_loop_run(loop);
    //g_main_loop_unref(loop);

    while (true);
    // I will close file descriptor
    return 0;

} 

Answer 1:

您需要使用GMainContext ,如果你想从运行一个线程主循环。 从油嘴的主循环文档 :

以允许的源的多个独立集来在不同的线程来处理,每个源与GMainContext相关联。 甲GMainContext只能在单个线程中运行,但源可以从其他线程被加入到它并除去从它。

当你创建一个主循环g_main_loop_new(NULL, FALSE); ,而它的方便指定任何GMainContext,你需要通过从你希望你的循环一个GMainContext如果你想运行在不同的线程循环。 您可以创建一个GMainContextg_main_context_new()并把它传递给g_main_loop_new()或使用g_main_context_get_thread_default()以获取正在运行的线程默认的主上下文。

g_io_add_watch()是函数的又一个方便的版本,

添加GIOChannel与默认优先级的默认主循环环境。

不幸的是,没有g_io_add_watch()的变体功能来指定一个主背景下,您必须手动创建一个GSourceGIOChannelp_hci_io ,并通过连接到您的上下文g_source_attach() 需要注意的是g_io_add_watch_full()还与默认的主上下文。

你的第二个代码工作的原因是,你在其中具有连接源的主线程创建了主循环。



文章来源: GLib GMainContext in a thread?
标签: c glib