当使用 glib 通过 调度信号时emit
,所有“侦听器”/处理程序是背靠背调用还是在每个侦听器/处理程序之后将控制权交给事件循环?
问问题
2052 次
2 回答
9
回调都被背靠背调用,而不会放弃对主循环的控制。
实际上,据我所知, g_signal_emit() 甚至在调用所有处理程序之前都不会返回控制权,因此主循环没有机会启动。
所以回答这篇文章标题中的问题:不,glib 信号不是异步的。
于 2010-01-28T04:05:57.537 回答
5
GLib 信号可以同步或异步处理。GObject 信号始终是同步的,即当您发出一个信号时,它在信号被处理之前不会返回。要使用 GLib 异步处理信号,(为了简洁起见,我使用 vala - 使用 vala 编译器将代码转换为纯 C)您必须定义一个信号源,或使用预定义的信号源,例如 IdleSource 或 TimeoutSource(当I/O 是没有问题的)。例如假设你有一个函数
void my_func() {
stdout.puts("Hello world! (async)\n");
}
并且你想异步调用它(从同一个线程!)从
void caller() {
// Here you want to insert the asynchronous call
// that will be invoked AFTER caller has returned.
// Body of caller follows:
stdout.puts("Hello world!\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 信号源。MainLoop 必须正在运行,否则这将不起作用。
文档:
于 2017-02-23T07:34:22.540 回答