GLib сигналы могут обрабатываться синхронно или асинхронно. Сигналы GObject всегда являются синхронными, то есть, когда вы излучаете сигнал, он не возвращается, пока сигнал не будет обработан.
Чтобы асинхронно обрабатывать сигнал с помощью GLib (я использую vala для краткости - используйте компилятор vala для преобразования кода в простой C), вы должны определить источник сигнала или использовать предопределенный, например IdleSource или TimeoutSource (когда Ввод / вывод исключен). Например, предположим, что у вас есть функция
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 должен быть запущен, иначе это не будет работать.
Документация: