Asynchronous glib信号是异步的吗?

Asynchronous glib信号是异步的吗?,asynchronous,signals,gnome,glib,Asynchronous,Signals,Gnome,Glib,当使用glib通过emit发送信号时,是将所有“侦听器”/处理程序背靠背调用,还是在每个侦听器/处理程序之后将控制权放弃给事件循环?将所有回调都背靠背调用,而不将控制权放弃给主循环 实际上,据我所知,在调用所有处理程序之前,g_signal_emit()甚至不会返回控制,因此主循环没有机会启动 所以要回答这篇文章标题中的问题:不,glib信号不是异步的。glib信号可以同步或异步处理。GObject信号始终是同步的,即当您发出信号时,它不会返回,直到信号得到处理。 要使用GLib异步处理信号(为

当使用glib通过
emit
发送信号时,是将所有“侦听器”/处理程序背靠背调用,还是在每个侦听器/处理程序之后将控制权放弃给事件循环?

将所有回调都背靠背调用,而不将控制权放弃给主循环

实际上,据我所知,在调用所有处理程序之前,g_signal_emit()甚至不会返回控制,因此主循环没有机会启动


所以要回答这篇文章标题中的问题:不,glib信号不是异步的。

glib信号可以同步或异步处理。GObject信号始终是同步的,即当您发出信号时,它不会返回,直到信号得到处理。 要使用GLib异步处理信号(为了简洁起见,我使用vala-使用vala编译器将代码转换为纯C),您必须定义一个信号源,或者使用预定义的信号源,例如IdleSource或TimeoutSource(当I/O不存在问题时)。例如,假设您有一个函数

void my_func() {
  stdout.puts("Hello world! (async)\n");
}
您希望从中异步调用它(从同一线程!)

以下是您的操作方法:

void caller() {
  // Code for the asynchronous call:
  var ev = new IdleSource();
  ev.set_callback(() => {
    my_func();
    return Source.REMOVE; // Source.REMOVE = false
  });
  ev.attach(MainContext.default());
  // Body of caller follows:
  stdout.puts("Hello world!\n");
}
您将获得以下输出:

Hello world!
Hello world! (async)
my_func()函数将在MainLoop空闲时执行(即,它没有其他要处理的信号)。要在经过特定时间间隔后触发,请使用TimeoutSource信号源。主循环必须正在运行,否则将无法工作

文件:

Hello world!
Hello world! (async)