本实验是按照《Linux高性能服务器编程》15.5节实现的。原理很简单,就是利用epoll+多线程对客户请求进行处理。代码已经放在了git仓库,下面记录了几个我遇到的问题。
1.异常表现:在进行压测时,服务器会触发许多对-1文件描述符的异常关闭。
这个问题我排查了很久,最后发现原来是因为自己不熟悉多线程编程而导致的。
对于每一个客户连接我都使用一个实体类来表示,其中也包括这个连接的文件描述符也就是connectFd。每一次处理完之后我当然要在server端对连接进行主动关闭所以就有了下面代码中的close。下面是正确的代码形式,但在存在bug的代码中,我的connectFd = -1是写在close之后的,bug就此埋下。
其实在我手动不断刷新请求的情况下服务器是能够正常工作的,但怪就怪在进行压测的时候原本正常的程序就会出现异常表现,从而我们可以确定:客户连接的快慢是导致bug出现的主要原因。
最后排查出来的结果就是文件描述符的修改不应该放在close之后,因为close了文件描述符之后系统就会有可能将下一个连接的描述符取为与被关闭的描述符相同的值,而在我的设计中相同的值意味着访问了相同的实体。若客户连接过快,则新连接符就会在connectFd=-1之前,close之后执行,如此一来新连接的connectFd就会被设置为-1,也就是说前一个运行较慢的线程将后一个线程中的数据进行了修改从而产生了这样子意想不到的错误。
知道了真正的问题所在后解决方案自然就很简单了。
void HttpConnection::pro