【问题标题】:Forcing immediate handling of events in Glib with C使用 C 强制立即处理 Glib 中的事件
【发布时间】:2015-10-07 12:09:46
【问题描述】:

针对 Bluez 的 C GDBus API 进行编程,我注意到我通过代理使用 DBUS 进行的方法调用在主循环结束之前不会返回结果。

例如,在终端应用程序中键入我创建的函数“cmd_bpm”会执行以下操作:

cmd_scan("on"); //Outputs "Discovery started", then posts results through a callback.
printf("test"); 
cmd_scan("off"); //Outputs "Discovery stopped", then posts results through a callback.

但是,这些回调直到GMainLoop 结束时才被处理。输出是:

test
discovery started
discovery stopped

虽然靠输出检查消息调用的顺序不是我做过的;我知道打印与行缓冲区有关。但是通过脚本断点表明回调总是在循环结束时处理。 有什么方法可以强制 glib 在调用这些事件时处理它们。例如。等待回复,运行回调,然后继续代码。而不是等待代码运行然后执行所有回调函数。我什至不确定 glib 是否是罪魁祸首,因为试图强制主循环迭代是不成功的。

我也尝试让 dbus 方法调用阻塞并等待回复,但我使用 cmd_scan() 执行的 StartDiscovery() 函数是 void,所以没有回复。

我想提供更多信息,但我不知道该包括什么,我在任何地方都没有注意到类似的主题。

准备主循环和回调。

main_loop = g_main_loop_new(NULL, FALSE);
dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);

signal = setup_signalfd();

client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");

g_dbus_client_set_connect_watch(client, connect_handler, NULL);
g_dbus_client_set_disconnect_watch(client, disconnect_handler, NULL);
g_dbus_client_set_signal_watch(client, message_handler, NULL);
g_dbus_client_set_proxy_handlers(client, proxy_added, proxy_removed,
                        property_changed, NULL);

input = 0;

g_dbus_client_set_ready_watch(client, client_ready, &input);

g_main_loop_run(main_loop);

在这个主循环中,我可以输入用户命令。

【问题讨论】:

  • 到终端的 I/O 通常是行缓冲的。因此,您应该尝试 printf("test\n"); ,并在您打印到标准输出的其他任何地方添加一个 \n 。 (或调用 fflush(stdout) )。如果您的问题没有解决,请发布一个完整的、最小的代码示例。
  • 我确实试过了,但我忘了添加它。但是,我并不是说要修复输出;没有调用整个回调函数,我想强制应用程序在我调用 cmd_scan 时立即调度回调。我将编辑我的答案以使其更清楚。谢谢!
  • 这只是一个评论,因为 \n 可能会使回调看起来没有被调用,因为在这种情况下输出将被延迟,而工作实际上已经完成 - 你只是不要不会立即在屏幕上看到它。但是,您需要发布更完整的代码以供人们帮助您。
  • 就是这样;工作没有完成。我不愿意发布代码,因为我认为这也是一个概念性问题,因为我想知道如何强制 GMainloop 在中断后立即调度回调,而不是在循环结束时调度。
  • 现在你可以做的一件事是你已经有了 D-Bus 的东西,那就是用主循环作为 D-Bus 服务来实现你的代码,并通过例如驱动测试。 dbus-send 或类似 D-Feet 的东西。这样,您的事件入口点将使用相同的机制,即 GDBus,它可能会简化故障排除并使测试更具可扩展性。

标签: c readline glib dbus bluez


【解决方案1】:

GDBus 具有所有方法调用函数的同步版本。例如。而不是调用g_dbus_proxy_call(),而是调用g_dbus_proxy_call_sync()

有些方法在出现任何“结果”之前就返回:StartDiscovery() 可能就是其中之一——甚至顾名思义它只是开始发现:它不会等待发现结果出现才返回,而是会发送信号或当结果可用时,属性会发生变化。如果您需要在执行某项操作之前等待这些结果,那么您必须在信号(或属性更改)处理程序中执行该操作,而不是在主代码体中。

【讨论】:

  • 明确的答案。介绍了一个新的见解(在回调/属性更改处理程序中实现功能)并解释了两个方法调用函数。谢谢!
猜你喜欢
  • 1970-01-01
  • 2017-07-28
  • 1970-01-01
  • 1970-01-01
  • 2011-09-17
  • 2019-03-27
  • 2019-12-28
  • 1970-01-01
  • 2015-09-17
相关资源
最近更新 更多