使用 C++14 和 GLib (GDBus) 的线程通信

Thread communication using C++14 and GLib (GDBus)

我正在设计一个 class,它将创建另一个 运行 并行的对象。这个并行对象将 运行 a GMainLoop 并监听各种事件(在本例中为 DBus)。我的问题是我不确定如何与 GMainLoop 中的线程 运行ning 通信。我是否被迫使用 GLib 方法与该线程通信?我宁愿依赖标准库,因为希望我最终能够完全消除对 GLib 的依赖。这是我正在努力完成的玩具示例:

// Example program
#include <iostream>
#include <thread>
#include <memory>

#include <glib.h>

class ParallelTask
{
public:
ParallelTask() {
    std::cout << "I am alive!\n";

    // initialize _mainLoop (allocate, add signals, set priority, etc)
    // ...

    g_main_loop_run(_mainLoop);
};
~ParallelTask() {
    std::cout << "I am dead!\n";

    // Misc cleanup
    // ...

    g_main_loop_quit(_mainLoop);
}
private:
GMainLoop* _mainLoop;
};

class TaskManager
{
public:
TaskManager() = default;
~TaskManager() {join();}

void startTask() {

    _thread = std::thread([this](){_task = std::make_unique<ParallelTask>();}); 
}
void stopTask() {
    //??? Need to send message to Parallel task telling it to shut down
    join();
}

private:
void join() {
    if (_thread.joinable()) {
        _thread.join();
    }
};

std::thread _thread;
std::unique_ptr<ParallelTask> _task;
};

int main()
{
    TaskManager taskManager;
    taskManager.startTask();

    // Do other stuff

    taskManager.stopTask();
}

此外,我 运行 正在 Linux 基于 OS。我什至更喜欢基于 pthread 的解决方案而不是 GLib 解决方案。但是,如果没有其他解决方案,我很乐意接受 GLib 的建议。谢谢!

我确定可以根据需要使用 g_main_context_iteration 而不是 g_main_loop_run。这允许我在我自己的 while 循环中处理所有 GLib 主循环事件。这让我可以灵活地使用各种 std 线程实用程序,例如 std::condition_variablestd::mutexstd::shared_ptr。如何使用 g_main_context_iteration:

的示例
#include <iostream>
#include <string>
#include <thread>
#include <atomic>
#include <chrono>

#include <glib.h>

using namespace std::chrono_literals;

void concurrentTask(std::atomic_bool& process)
{
    std::cout << "Beginning processing\n";

    GMainContext *context = g_main_context_default();

    // Register signals, etc...

    while (process == true)
    {
        g_main_context_iteration(context, true);
    }

    g_main_context_unref(context);
}

int main()
{
    std::atomic_bool process(true);

    std::thread task(concurrentTask, std::ref(process));

    std::this_thread::sleep_for(2s);
    process = false;
    task.join();
    std::cout << "Processing complete\n";
}