我有一个问题使用Glib。我想订阅一个dbus信号,而不使用g_main_loop_run启动主循环。
创建到正确总线的连接,并调用函数g_dbus_connection_signal_subscribe。
我将main函数中对g_main_loop_run的调用替换为while(1)。
不幸的是,它不起作用。如果我正确地理解了GLib,就不需要为这样的处理启动主循环。
请帮助。
示例代码: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);
如果我正确理解了GLib,就不需要启动
如果你想等待传入的DBus事件,你必须运行main循环。主循环所做的是等待和处理事件,您希望等待然后处理事件。作为g_main_loop_run
的替代,您可以尝试在while(1)
中运行g_main_context_iteration
。
我也有类似的需要以非阻塞的方式处理GLib事件,但我在任何地方都找不到完整的答案,所以我在这里发布了我的解决方案以供参考。
el。pescado说,g_main_loop_run()
的一个替代方案是在GMainLoop
对象的上下文中反复调用g_main_context_iteration()
。这可以在循环中完成,例如,允许在事件处理周期之间执行一些intervening_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