gpt4 book ai didi

c - 基于 C 中的 "quit"标志正确终止 GLib 主循环

转载 作者:行者123 更新时间:2023-12-04 10:17:06 28 4
gpt4 key购买 nike

我意识到这可能是一个新手 GLib 问题,但我很难找到解决下面我的问题的代码示例。因此,在我走错路之前,我希望得到您的建议。

我的代码监听 D-Bus 消息。一条 D-Bus 消息是“退出”消息,旨在指示主循环关闭。如果主循环中没有其他任务,一个简单的解决方案是调用 g_main_loop_run()在下面的代码中并让 D-Bus 消息处理代码(此处未显示)执行 g_main_loop_quit()当收到“退出”消息时。

但是,我更喜欢由主循环做出退出决定,除了监听 D-Bus 消息之外,它还可以执行各种其他任务。以下代码在设置工作 D-Bus 服务器后按预期执行此操作:

GMainLoop *glib_mainloop = g_main_loop_new( NULL, false );
/* Set up the D-Bus connection to work in the GLib event loop. */
dbus_connection_setup_with_g_main( dbus_connection, NULL );

/* Run the GLib event loop. */
GMainContext *glib_context = g_main_context_default( );
while( quit_indicator == false )
{
g_main_context_iteration( glib_context, /*allow blocking=*/false );
/* Do a variety of other tasks. */
}

g_main_loop_quit( glib_mainloop );

注意:以上是说明我的问题的最少代码,我知道主循环中的“其他任务”可能由线程更好地处理, GSource s,或其他方式。例如,如果按原样使用上述代码,则会出现明显的忙等待或计时问题。

我的问题是:上面的代码示例是完成我想要的正确方法还是有更“真实”的 GLib 方法?

最佳答案

你的方法基本正确。很多例子说要使用g_main_loop_run()g_main_loop_quit()来控制主上下文,但在你做的时候手动迭代主上下文会更清楚。

应该对您的代码进行的一项更改是告诉 g_main_context_iteration()允许阻塞,否则你的主循环本质上是一个繁忙的循环,你的进程在等待 I/O 时不会休眠。您也不需要使用 GMainLoop如果你迭代 GMainContext手动。

另一个必要的更改是调用 g_main_context_wakeup()g_main_context_iteration() 中的阻塞中唤醒主上下文当您更改终止条件的值时。

三、创建和退出GMainLoopg_main_loop_new()/g_main_loop_quit()在您的代码中什么都不做,因为 GMainLoop永远不会与 g_main_loop_run() 一起运行.挂断那些电话。

这是一个更新的版本:

GMainContext *context = g_main_context_default ();
gboolean quit = FALSE;

/* Set up the D-Bus connection to work in the GLib event loop. */
dbus_connection_setup_with_g_main (dbus_connection, context);

/* Run the GLib event loop. */
while (!quit)
g_main_context_iteration (context, TRUE);

/* To exit the main loop (from a callback implementing your D-Bus Quit() function): */
quit = TRUE;
g_main_context_wakeup (NULL /* global default main context */);

其他几点:
  • 正如您所指出的,您评论中的“其他任务”应该在主上下文的回调中执行。
  • 使用 GDBus 而不是 dbus-glib(已弃用且未维护)。我写过an answer here关于为什么以及如何选择 D-Bus 绑定(bind)。
  • 如果您要在新线程(不是主线程)中执行此操作,您应该使用新的 GMainContextg_autoptr(GMainContext) context = g_main_context_new (); g_main_context_push_thread_default (context); .你不应该分享 GMainContext多个线程之间。虽然这样做是安全的,但它并不高效。

  • 这是使用这些技术的现代基于 GLib 的守护程序中的主循环的 MPL 许可示例: https://git.apertis.org/cgit/rhosydd.git/tree/libcroesor/service.c#n569

    关于c - 基于 C 中的 "quit"标志正确终止 GLib 主循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48149520/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com