是否是异步的glib信号?
答
这些回调都是背靠背调用而不会放弃对主循环的控制。
实际上,据我所知,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() {
// 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)
当MainLoop空闲时,my_func()函数将被执行(即,它没有其他信号要处理)。要在特定时间间隔过后触发,请使用TimeoutSource信号源。 MainLoop必须正在运行,否则这将不起作用。
文档: