CherryPy服务器使用线程来处理请求。我的线程服务器中的一种特殊方法非常复杂,而且CPU很繁重,所以我必须使用方法请求线程内的多处理来并行执行。如何将多处理与多线程一起使用?
我想我只是
def expensive_method(self):
pool = Pool()
x = pool.map(fnc, args)
pool.terminate()
更换
class Server(object)
@cherrypy.expose
def expensive_method(self):
...
x = map(fnc, args)
...
def fnc(args):
# this method doesn't need CherryPy but is expensive to compute
...
cherrypy.quickstart(Server())
(其中正常工作),但不起作用。即使在简单的情况下,当我不使用在所有的游泳池,
def expensive_method(self):
pool = Pool()
x = map(fnc, args) # <== no pool here! same as the working example
pool.terminate()
我得到一个异常
[08/Jan/2013:20:05:33] ENGINE Caught signal SIGTERM.
2013-01-08 20:05:33,919 : INFO : _cplogging:201 : error(CP Server Thread-3) : [08/Jan/2013:20:05:33] ENGINE Caught signal SIGTERM.
[08/Jan/2013:20:05:33] ENGINE Bus STOPPING
2013-01-08 20:05:33,920 : INFO : _cplogging:201 : error(CP Server Thread-3) : [08/Jan/2013:20:05:33] ENGINE Bus STOPPING
[08/Jan/2013:20:05:38] ENGINE Error in 'stop' listener <bound method Server.stop of <cherrypy._cpserver.Server object at 0x1090c3c90>>
Traceback (most recent call last):
File "/Volumes/work/workspace/vew/prj/lib/python2.7/site-packages/cherrypy/process/wspbus.py", line 197, in publish
output.append(listener(*args, **kwargs))
File "/Volumes/work/workspace/vew/prj/lib/python2.7/site-packages/cherrypy/process/servers.py", line 223, in stop
wait_for_free_port(*self.bind_addr)
File "/Volumes/work/workspace/vew/prj/lib/python2.7/site-packages/cherrypy/process/servers.py", line 410, in wait_for_free_port
raise IOError("Port %r not free on %r" % (port, host))
IOError: Port 8888 not free on '127.0.0.1'
我认为这发生在请求结束,之后或期间pool.terminate()
。
分叉的工作进程不会对服务器或端口做任何事情。有没有办法告诉CherryPy和/或多处理忽略“服务器位”? fnc
中我不需要任何端口或套接字。
我需要这个工作在OSX + Linux上,使用Python 2.7.1和CherryPy 3.2.2。
进展1:
按西尔的建议下,我尝试pool = Pool(initializer=cherrypy.server.unsubscribe)
。没有更多的例外,一切工作正常,但在我看到的日志
[08/Jan/2013:21:16:35] ENGINE Caught signal SIGTERM.
2013-01-08 21:16:35,908 : INFO : _cplogging:201 : error(CP Server Thread-10) : [08/Jan/2013:21:16:35] ENGINE Caught signal SIGTERM.
[08/Jan/2013:21:16:35] ENGINE Bus STOPPING
2013-01-08 21:16:35,909 : INFO : _cplogging:201 : error(CP Server Thread-10) : [08/Jan/2013:21:16:35] ENGINE Bus STOPPING
[08/Jan/2013:21:16:35] ENGINE Bus STOPPED
2013-01-08 21:16:35,909 : INFO : _cplogging:201 : error(CP Server Thread-10) : [08/Jan/2013:21:16:35] ENGINE Bus STOPPED
[08/Jan/2013:21:16:35] ENGINE Bus EXITING
2013-01-08 21:16:35,909 : INFO : _cplogging:201 : error(CP Server Thread-10) : [08/Jan/2013:21:16:35] ENGINE Bus EXITING
[08/Jan/2013:21:16:35] ENGINE Bus EXITED
2013-01-08 21:16:35,910 : INFO : _cplogging:201 : error(CP Server Thread-10) : [08/Jan/2013:21:16:35] ENGINE Bus EXITED
这样好吗?难道这会产生任何麻烦(比如说,当同时在不同线程中提供多个请求时)?
进展2:
其实上面的叶子空闲进程背后偶尔:(因此,这是行不通的精细奇怪的是,这些闲置的过程是由Pool
催生,所以他们应该是守护进程。但他们甚至杀害父后实际活路
正在进行中3:
我感动分岔(= Pool()
调用)在请求处理方法之外,但之后初始化所有必要的状态(以便工作进程可以看到这个状态)。没有更多的错误或例外。
底线:多处理和多线程不能一起工作。
感谢。你可以尝试使fnc成为实际的模块级功能而不是方法吗? –
我可能不会在CherryPy页面处理程序中创建池。线程和多进程并不总是最好的朋友,因为我最近了解到http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them –
该死的我还没有正确地阅读你的初始文章。如果你不需要服务器,只需在快速启动调用之前执行:'cherrypy.server.unsubscribe()'。 –