在mod_wsgi上保持web.py应用的并发性
抱歉如果这段话让你感到困惑。如果需要进一步解释,请留言。
我正在用web.py写一个小的文件上传应用,并通过mod_wsgi和apache来部署它。我在管理会话时遇到了一些问题,想了解一下web.py中的线程是怎么工作的。
简单来说,我在用户访问我的页面时,会在渲染的HTML页面中嵌入一段代码,放在一个隐藏的字段里。文件上传是通过一个标准的POST请求来完成的,这个请求里包含了文件和那段代码。然后,我通过在文件上传的POST方法中更新进度,并用GET请求从另一个类中获取进度。这个“会话”(抱歉我说得比较简单)是存储在一个会话对象中的,像这样:
class session:
def __init__(self):
self.progress = 0
self.title = ""
self.finished = False
def advance(self):
self.progress = self.progress + 1
所有的会话都保存在我应用脚本中的一个全局字典里,然后用我之前提到的代码作为键来访问。
但不知为什么,我的进度一直停在0,没法增加。我调试了几个小时,发现上传类和进度类引用的两个会话对象并不是同一个。不过这两个代码(就我所知)是相等的。这让我很抓狂,因为在我本地机器上的web.py测试服务器上,这一切都正常工作。
编辑:经过一些研究,我发现这个字典可能会在每个请求中被复制。我尝试把字典放在另一个地方并导入,但这并不奏效。有没有其他方法可以在不使用数据库的情况下“分开”会话字典呢?
2 个回答
来自 PEP 333,定义了WSGI:
能够同时处理多个请求的服务器,也应该提供以单线程方式运行应用程序的选项,这样那些不支持多线程的应用或框架仍然可以在该服务器上使用。
请查看你所使用的WSGI服务器的文档。
Apache/mod_wsgi可以在多进程的配置下运行,这意味着你的请求可能并不是由同一个进程来处理的。如果每个进程都是单线程的,那么在上传文件的时候,这个进程就不能处理其他请求了。想了解更多,可以看看这篇文章:
http://code.google.com/p/modwsgi/wiki/ProcessesAndThreading
你可能应该考虑使用mod_wsgi的守护进程模式,这样可以让一个进程有多个线程。