关于reactor的内部机制(浅析) -- dreamingk [2004-08-09 02:21:09]
刚才向hd讨教了一些关于reactor的问题,受益非浅,这里把它写下来。
精髓描述
reactor内部有一个event loop, 根据事件的类型, 调用不同的事件响应函数,这些函数是事先注册的callback object.
详细
::
- 这里调用fun1,fun2是阻塞调用的,就是说只有fun1执行完才能接着下一次loop,这样如果fun1执行的时间太长,
事件就会阻塞在事件队列里面。
而实际项目中,fun1,fun2很难保证能马上返回,可能要查询数据库什么的,因此这里必须想办法,比如多线程什么的,而twisted提供了deffered对象来提供帮助。
在Cpython中,reactor对网络数据的读写是用select实现的,每个需要回调的对象都是abstract.FileDescriptor派生类的实例。该对象 实现了fileno方法,以返回fd供select用,还要实现了doWrite和doRead方法供回调。该对象的startReading,startWriting方法会将回调的 对象加入到reactor的读写队列中(实际在reactor中是dict)。当reactor的主循环工作时,它首先去检查那些用Calllator登记过的函数是否到 了时间,如到了就运行它们,然后调用select,并将读写队列中的对象传递给它,此外还需根据CallLater函数队列中的时间设置一个合适的超时。 当select返回时,再根据返回的结果调用相应对象的doRead,doWrite方法。 此外,如上面提到的,CallLater函数可以将函数登记到回调队列中。 ---0.706
后记体会
这里其实和UI框架中的主事件循环很象,只是各种框架的响应事件的机制不同,MFC是用映射表,Java的swing使用interface,跟twisted有些象,qt使用的是信号/信号槽机制,各有利弊吧。
这些道理其实很简单,俺只是以为twisted为每个连接开一线程呢,所以不知道为什么要用deffered。