我有简单的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次。
任何想法如何让它发挥作用?
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机器运行这个脚本很好。
答案 0 :(得分:4)
scikit_learn显然使用multiprocessing
模块来实现并发。 multiprocessing
使用pickle
在进程之间传输数据,其中包括它引起的特殊问题,将导致在您的父进程中导入的某些模块被导入到您的工作进程中。 / p>
然而,你的PLS_web.py
“模块”实际上不是一个模块,而是一个脚本;由于您已将reactor.listenTCP
和reactor.run
放在其底部,因此在导入时实际上会执行而不是仅加载其代码。
这个特殊错误是因为你的web服务器正在运行4次(对于控制器进程一次,对于三个作业中的每一个都运行一次),因为第一个服务器已经是第一个服务器听12000端口。
您应该将其他位置的reactor.run
/ reactor.listenTCP
行删除到顶级脚本中。一个好的经验法则是这些行不应该出现在与class
或def
语句相同的文件中;在一个地方定义您的代码并在另一个地方启动它。将其移动到未导入的文件后(您可能希望将其放在名称不是合法模块标识符的文件中,如run-my-server.py
),然后multiprocessing
可能能够导入所需的所有代码并完成其工作。
更好的是,不要写那些行,写一个twisted application plugin并用twistd
运行你的程序。如果您不必将reactor.run
语句放在任何地方,则不能将其置于错误的位置:)。