同步异步 阻塞非阻塞 事件

来源:互联网 发布:张大千 敦煌破坏 知乎 编辑:程序博客网 时间:2024/06/07 01:50

一般的,几乎所有的 IO 接口都是阻塞型的。进程,内核,系统调用。

同步与异步,阻塞与非阻塞。异步阻塞没有多大意义,实际当中不会使用到。

下图来自网络,陈硕在知乎上的回答:


Qt中所有的事件都是protected virtual,既然是虚函数,由于多态的存在;如果不加域运算符,如果需要在派生类的事件处理中使用基类对该事件的处理,可以在派生类的改事件处理虚函数中,使用域运算符,调用基类的虚函数;这相当于事件在继承层次上的传递。Qt中的事件可以设置接收与忽略,表示事件在对象树层次上的传递。默认情况下,事件都是接受的,表示不向上传递;作为所有控件的QWidget的事件处理,却是忽略的。


Qt中的事件处理可以分为五种情况,功能由弱到强,处理顺序由后到前:

1、实现处理该事件类型对应的事件处理函数。

protected:virtual bool QObject::event(QEvent *e)

2、event() 函数的本质是一个大switch分支,相当于事件分类器;然后在每一类中,再按照对应类型的事件处理函数处理。也就是说1中的事件类型对应的处理函数,实际上是在 event() 函数中被调用的。event() 函数的返回值为 true 表示该事件被识别并被处理,否则返回值为false。

sendEvent()直接进行事件的派发与处理,通过调用 notify() 实现,是同步的;而postEvent() 则是将事件加入到事件队列当中,由于存在事件队列,所以是异步的。

public:void QObject::installEventFilter( QObject * filterObj);virtual bool QObject::eventFilter ( QObject * watched, QEvent * event );

3、实际上,在执行对象的事件处理函数时,会先检查该对象的 eventFilters 事件过滤器对象列表,如果该列表非空,则会执行事件过滤列表中的所有对象eventFilter() 函数。也就是说B给A安装了事件过滤器(通过A .installEventFilter(&B)实现,那么派发给A的事件,会先经过B的eventFilter()函数的处理)。eventFilter()函数的通常用法为第一个参数用来判断是不是感兴趣的目标,第二个参数用来判断事件的类型。返回值为true 表示过滤掉这个事件,事件处理就此终止,false表示继续传递。每个对象可以被安装多个事件过滤器,过滤器以安装的次序的反序被调用。


QCoreApplication 和其子类 QApplication 都继承自QObject。

public:virtual bool QCoreApplication::notify ( QObject * receiver, QEvent * event );

4、Qt的事件派发是由main() 函数中的QApplication 对象app开始的(所有对象的事件最开始都是由app 对象来处理),同样也可以为app 安装事件过滤器。在事件过滤器中进行第一步处理,接着进行事件的派发 receiver->event(event)。然后进到第三步。这是一个全局的事件过滤器,作用在所有线程,虽然使用在主线程当中。

注意这里后边三个函数的返回类型都是bool,值为true 表示处理就此结束;false表示仍然还有派发。


5、继承 QApplication 类 , 并重写 notify() 函数。主线程中的app 对象就是通过这个函数为所有的线程中的对象分发事件。notify() 函数中最先进行的就是app 函数的事件过滤器。参见帮助文档中的函数说明。










1 0
原创粉丝点击