请求内的Twisted _delayedRender内的多线程调用

时间:2014-07-17 08:11:59

标签: python multithreading twisted scikit-learn

我有简单的Twisted webserver应用程序来处理我的数学请求。一切正常(我隐藏了与我的问题无关的大代码片段):

#import section ...

class PlsPage(Resource):
    isLeaf = True

    def render_POST(self, request):
        reactor.callLater(0, self._delayedRender, request)
        return NOT_DONE_YET

    def _delayedRender(self, request):

        #some actions before
        crossval_scores = cross_validation.cross_val_score(pls1, X, y=numpy.asarray(Y), scoring=my_custom_scorer, cv=KFold(700, n_folds=700))
        #some actions after

        request.finish()

reactor.listenTCP(12000, server.Site(PlsPage()))
reactor.run()

当我尝试通过将cross_validation设置为3来加快n_jobs计算时。

crossval_scores = cross_validation.cross_val_score(pls1, X, y=numpy.asarray(Y), scoring=my_custom_scorer, cv=KFold(700, n_folds=700), n_jobs=3)

之后我得到了3个例外:

twisted.internet.error.CannotListenError:无法监听任何:12000:[Errno 10048]通常只允许使用每个套接字地址(协议/网络地址/端口)。

出于某些原因,我无法通过n_jobs>调用cross_val_score 1在_delayedRender里面。 这是异常的追溯,由于某些原因,reactor.listenTCP也试图启动3次。

Exception traceback

任何想法如何让它发挥作用?

UPD1。我创建文件PLS.py并将所有代码移到此处,除了最后两行:

from twisted.web import server
from twisted.internet import reactor, threads
import PLS

reactor.listenTCP(12000, server.Site(PLS.PlsPage()))
reactor.run()

但问题仍然存在。我还发现此问题仅在Windows上存在。我的Linux机器运行这个脚本很好。

1 个答案:

答案 0 :(得分:4)

scikit_learn显然使用multiprocessing模块来实现并发。 multiprocessing使用pickle在进程之间传输数据,其中包括它引起的特殊问题,将导致在您的父进程中导入的某些模块被导入到您的工作进程中。 / p>

然而,你的PLS_web.py“模块”实际上不是一个模块,而是一个脚本;由于您已将reactor.listenTCPreactor.run放在其底部,因此在导入时实际上会执行而不是仅加载其代码。

这个特殊错误是因为你的web服务器正在运行4次(对于控制器进程一次,对于三个作业中的每一个都运行一次),因为第一个服务器已经是第一个服务器听12000端口。

您应该将其他位置的reactor.run / reactor.listenTCP行删除到顶级脚本中。一个好的经验法则是这些行不应该出现在与classdef语句相同的文件中;在一个地方定义您的代码并在另一个地方启动它。将其移动到未导入的文件后(您可能希望将其放在名称不是合法模块标识符的文件中,如run-my-server.py),然后multiprocessing 可能能够导入所需的所有代码并完成其工作。

更好的是,不要写那些行,写一个twisted application plugin并用twistd运行你的程序。如果您不必将reactor.run语句放在任何地方,则不能将其置于错误的位置:)。