1

我正在尝试创建一个自定义GMainContext*(以免与 Qt/etc 冲突)并在自定义线程上处理循环。

我正在使用libnm(用于 NetworkManager),但我认为它不相关。

使用自定义GMainContext*.

#include <NetworkManager.h>
#include <iostream>
#include <thread>

// Uncomment this for it to not work.
#define WORKING

static void test_callback ()
{
    std::cerr << "test callback";
}

static int thread(GMainContext *mainContext)
{
    GMainLoop* mainLoop = g_main_loop_new(mainContext, FALSE);
    g_main_loop_run(mainLoop);
}

int main(int argc, char *argv[])
{
#ifdef WORKING
    GMainContext* mainContext = g_main_context_default();
#else
    GMainContext* mainContext = g_main_context_new();
    g_main_context_push_thread_default(mainContext);
#endif

    GError* error = nullptr;
    NMClient* client = nm_client_new(nullptr, &error);

    g_signal_connect(client, NM_CLIENT_ACTIVE_CONNECTION_ADDED, G_CALLBACK(test_callback), nullptr);
    g_signal_connect(client, NM_CLIENT_ACTIVE_CONNECTION_REMOVED, G_CALLBACK(test_callback), nullptr);

    std::thread thread_obj(thread, mainContext);
    thread_obj.join();

    return 0;
}

信号处理程序使用已WORKING定义的正确引发,使用g_main_context_default().

4

1 回答 1

1

我怀疑这是因为至少一些底层的 libnmGSource仍然被添加到全局默认值GMainContext中(总是由返回的那个g_main_context_default())。如果要GMainContext在另一个线程中运行自定义,则需要确保所有GSources 都附加到它;或者您还需要GMainContext在主线程中运行全局默认值。

如果您尝试GMainContext在一个线程中运行并在主线程中运行 Qt 主循环,那么您将不得不考虑它们都涉及的数据的线程安全性。GMainContext从长远来看,将全局默认值链接到 Qt 主循环(反之亦然)可能更容易,这样您就只有一个事件循环在运行(在一个线程中)。那么你就不必考虑线程安全了。

于 2019-05-01T22:31:54.893 回答