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

时间:2017-07-22 14:35:32

标签: c++ multithreading thread-safety glib

我正在设计一个类,它将创建另一个并行运行的对象。此并行对象将运行GMainLoop并侦听各种事件(在本例中为DBus)。我的问题是我不确定如何与GMainLoop中运行的线程进行通信。我是否被迫使用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的操作系统上运行。我甚至更喜欢pthread基于GLib的解决方案。但是,如果没有其他解决办法,我很乐意接受GLib个建议。谢谢!

1 个答案:

答案 0 :(得分:0)

我已经确定,根据我的需要,我可以使用g_main_context_iteration代替g_main_loop_run。这允许我处理我自己的GLib循环中的所有while主循环事件。这使我可以灵活地使用各种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";
}