gc5*_*gc5 4 python ubuntu asynchronous cherrypy multiprocessing
我在Mac OS X和Ubuntu 14.04上运行此代码作为CherryPy Web服务.通过multiprocessing在python3上使用我想以worker()异步方式启动静态方法Process Pool.
相同的代码在Mac OS X上运行完美,在Ubuntu 14.04 worker()中无法运行.即通过调试POST方法内部的代码,我可以看到每一行都被执行 - 来自
reqid = str(uuid.uuid4())
Run Code Online (Sandbox Code Playgroud)
至
return handle_error(202, "Request ID: " + reqid)
Run Code Online (Sandbox Code Playgroud)
在Ubuntu 14.04中启动相同的代码,它不运行该worker()方法,甚至不在方法print()的顶部(将被记录).
这是相关代码(我只省略了handle_error()方法):
import cherrypy
import json
from lib import get_parameters, handle_error
from multiprocessing import Pool
import os
from pymatbridge import Matlab
import requests
import shutil
import uuid
from xml.etree import ElementTree
class Schedule(object):
exposed = True
def __init__(self, mlab_path, pool):
self.mlab_path = mlab_path
self.pool = pool
def POST(self, *paths, **params):
if validate(cherrypy.request.headers):
try:
reqid = str(uuid.uuid4())
path = os.path.join("results", reqid)
os.makedirs(path)
wargs = [(self.mlab_path, reqid)]
self.pool.apply_async(Schedule.worker, wargs)
return handle_error(202, "Request ID: " + reqid)
except:
return handle_error(500, "Internal Server Error")
else:
return handle_error(401, "Unauthorized")
#### this is not executed ####
@staticmethod
def worker(args):
mlab_path, reqid = args
mlab = Matlab(executable=mlab_path)
mlab.start()
mlab.run_code("cd mlab")
mlab.run_code("sched")
a = mlab.get_variable("a")
mlab.stop()
return reqid
####
# to start the Web Service
if __name__ == "__main__":
# start Web Service with some configuration
global_conf = {
"global": {
"server.environment": "production",
"engine.autoreload.on": True,
"engine.autoreload.frequency": 5,
"server.socket_host": "0.0.0.0",
"log.screen": False,
"log.access_file": "site.log",
"log.error_file": "site.log",
"server.socket_port": 8084
}
}
cherrypy.config.update(global_conf)
conf = {
"/": {
"request.dispatch": cherrypy.dispatch.MethodDispatcher(),
"tools.encode.debug": True,
"request.show_tracebacks": False
}
}
pool = Pool(3)
cherrypy.tree.mount(Schedule('matlab', pool), "/sched", conf)
# activate signal handler
if hasattr(cherrypy.engine, "signal_handler"):
cherrypy.engine.signal_handler.subscribe()
# start serving pages
cherrypy.engine.start()
cherrypy.engine.block()
Run Code Online (Sandbox Code Playgroud)
你的逻辑是隐藏你的问题.该apply_async方法返回一个AsyncResult对象,该对象充当您刚刚安排的异步任务的处理程序.当您忽略计划任务的结果时,整个事情看起来像是"无声地失败".
如果您尝试从该任务获得结果,您将看到真正的问题.
handler = self.pool.apply_async(Schedule.worker, wargs)
handler.get()
... traceback here ...
cPickle.PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
Run Code Online (Sandbox Code Playgroud)
简而言之,您必须确保传递给Pool的参数是Picklable.
如果它们所属的对象/类也是可选择的,则实例和类方法是Picklable.静态方法不可选,因为它们会松散与对象本身的关联,因此pickle库无法正确地序列化它们.
作为一般线,最好避免调度到multiprocessing.Pool与顶级定义函数不同的任何东西.
| 归档时间: |
|
| 查看次数: |
4001 次 |
| 最近记录: |