使用 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_variable
、std::mutex
和 std::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";
}
我正在设计一个 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_variable
、std::mutex
和 std::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";
}