是否是异步的glib信号?

问题描述:

当使用glib通过emit发送信号时,是否所有的“听众”/处理程序都称为背对背是否在每个侦听器/处理程序之后放弃到事件循环?是否是异步的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必须正在运行,否则这将不起作用。

文档: