我已经搜索了堆栈溢出以找到与我的问题相关的答案。但我没有找到答案。
我有一个主线程(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;

}

最佳答案

如果要从线程运行主循环,则需要使用GMainContext。从油嘴滑舌的main loop documentation
允许在中处理多个独立的源集
不同的线程,每个源都与GMainContext关联。一个
GMainContext只能在单个线程中运行,但源代码可以
从其他线程中添加和删除。
使用g_main_loop_new(NULL, FALSE);创建主循环时,虽然不指定任何GMainContext很方便,但如果要在其他线程中运行循环,则需要传递一个GMainContext。您可以使用GMainContext创建g_main_context_new()并将其传递给g_main_loop_new(),或者使用g_main_context_get_thread_default()获取运行线程的默认主上下文。
g_io_add_watch()是另一个方便的函数版本,它
使用
默认优先级。
不幸的是,没有g_io_add_watch()变量函数来指定主上下文,您必须从GSourceGIOChannel中手动创建p_hci_io,并通过g_source_attach()连接到上下文。注意g_io_add_watch_full()也适用于默认的主上下文。
您的第二个代码工作的原因是,您在附加了源代码的主线程中创建了主循环。

关于c - GLib GMainContext在线程中?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42395844/

10-10 21:54