序言
虽然Tufão的使用非常简单,具体可见QT使用记录。但并非没有使用不顺的情况。这篇文章用以记录Tufão使用过程中遇到的经验教训。
坑
1. 基础坑
1.1 Tufao::HttpServerRequest
和Tufao::HttpServerResponse
对象的生命周期及其所有权
QT的信号槽机制在单线程下表现非常良好,但在多线程下就开始有坑了。因为物理服务器一般是多核CPU,单线程应用实在无法充分利用,所以服务器应用一般应是多线程的(或者像CGI那样搞多进程)。而Tufão库通过Handler传递过来的Tufao::HttpServerRequest&
和Tufao::HttpServerResponse&
参数,其能在多线程下保证生命周期正常,不会产生悬挂指针吗?
经查询库源码。所有位于动态内存中的QObject
对象,在deleteLater()
被触发后,将由产生此对象的event loop在其下次的exec()中将其所有信号事件处理完毕后删除。因此此event loop在哪个线程里,此对象就相当于归哪个线程管。Tufao::HttpServerRequest
和Tufao::HttpServerResponse
对象便属于此类,其'deleteLater()'管道已与其关联的QTcpSocket
对象的disconnected()
信号相连接。因此,在跨线程时不能简单地复制Tufao::HttpServerRequest
和Tufao::HttpServerResponse
对象指针到新线程调用。在官方例子中,多线程的处理方法是通过向新线程传递socketDescriptor,在新线程里去创建QTcpSocket
、Tufao::HttpServerRequest
和Tufao::HttpServerResponse
对象及调用Handler的,保证了其调用的安全性。
当然,这样的使用肯定会限制其并发的性能。不过,强调并发的业务也不会在windows上跑就是了,所以这个库还是合格的。
(未完待续)