3

我在使用 Glib 时遇到问题。我想订阅 dbus 信号而不用 g_main_loop_run 启动主循环

我创建到正确总线的连接并调用函数g_dbus_connection_signal_subscribe

我用while(1) 替换了 main 函数中对g_main_loop_run的调用。

不幸的是,它不起作用。如果我正确理解 GLib,则无需启动 mainloop 进行此类处理。

请帮忙。

示例代码:

session_bus = g_bus_get_sync(G_BUS_TYPE_SESSION,
                             NULL,
                             NULL );


g_dbus_connection_signal_subscribe(session_bus,
                                   "org.freedesktop.Notifications",
                                   "org.freedesktop.Notifications",
                                   "NotificationClosed",
                                   "/org/freedesktop/Notifications",
                                   NULL,
                                   G_DBUS_SIGNAL_FLAGS_NONE,
                                   (GDBusSignalCallback) onNotifClosed,
                                   NULL,
                                   NULL );

loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
g_main_loop_unref(loop);
g_object_unref(session_bus);
4

2 回答 2

4

如果我正确理解 GLib,则无需启动 mainloop 进行此类处理。

如果要等待传入的 DBus 事件,则必须运行主循环。主循环所做的就是等待和处理事件,而你想等待然后处理事件。作为替代方案g_main_loop_run,您可以尝试运行g_main_context_iteration.while(1)

于 2014-05-19T13:28:56.910 回答
1

我有类似的需要以非阻塞方式处理 GLib 事件,但我在任何地方都找不到完整的答案,所以我在这里发布我的解决方案以供参考。

正如el.pescado所说,一种替代方法是重复g_main_loop_run()调用对象的上下文。例如,这可以在一个循环中完成,允许在事件处理周期之间执行一些,直到满足某种类型:g_main_context_iteration()GMainLoopintervening_task()termination_condition()

GMainLoop *loop = g_main_loop_new();
while (!termination_condition())
{
  g_main_context_iteration(g_main_loop_get_context(loop), FALSE);
  intervening_task();
}

g_main_loop_unref(loop);

在上面的代码片段中,循环上下文由 检索g_main_loop_get_context(),任何挂起的 GLib 事件由 处理g_main_context_iteration()。如果没有挂起的事件,将may_block参数设置为使函数立即返回(否则它将阻止等待处理某些内容)。FALSE

然而值得注意的是,如果以上就是您想要做的全部,那么您最好坚持g_main_loop_run()使用g_timeout_add()g_idle_add()注册干预任务和终止条件作为事件回调 - 后者将调用g_main_loop_quit()终止循环。这里的重点不是按原样使用该代码,而只是为了演示如何以非阻塞方式处理 GLib 事件,以便将其集成到另一个框架的主循环中。例如 Qt 或 ROS。

于 2020-10-28T20:35:31.303 回答