Python 如何将多处理与多线程结合使用?

Python 如何将多处理与多线程结合使用?,python,multithreading,multiprocessing,cherrypy,Python,Multithreading,Multiprocessing,Cherrypy,CherryPy服务器使用线程来处理请求。我的线程服务器中有一个特定的方法非常复杂,CPU非常繁重,因此我必须从方法请求线程内部使用多处理来并行执行 我想我应该换一个 class Server(object) @cherrypy.expose def expensive_method(self): ... x = map(fnc, args) ... def fnc(args): # this method doesn't

CherryPy服务器使用线程来处理请求。我的线程服务器中有一个特定的方法非常复杂,CPU非常繁重,因此我必须从方法请求线程内部使用多处理来并行执行

我想我应该换一个

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()
可以吗?这会带来什么麻烦(比如,在不同线程中同时服务多个请求时)


进展2:

事实上,上面提到的偶尔会留下空闲进程:(所以它不能正常工作。奇怪的是,这些空闲进程是由
Pool
产生的,所以它们应该是守护进程,但实际上即使杀死父进程,它们仍然是活动的


进展3:

我将forking(
Pool()
call)移到请求处理方法之外,但在初始化了所有必要的状态(以便工作进程可以看到此状态)之后,没有更多的错误或异常


一句话:多处理和多线程不能一起工作。

self指的是哪种类型的对象?在哪一点上初始化并启动分叉进程?也许多一点代码有助于诊断问题

好的,这个很好用:

import multiprocessing
import os
import time

import cherrypy

def run_in_sub_proc(size):
    for i in range(size):
        print os.getpid(), i
        time.sleep(1)

pool = multiprocessing.Pool(2)

class Root(object):
    @cherrypy.expose
    def index(self):
        pool.map_async(run_in_sub_proc, (3, 5))

if __name__ == '__main__':
    cherrypy.engine.subscribe('stop', pool.join)
    cherrypy.quickstart(Root())

谢谢。你能试着让fnc成为一个实际的模块级函数而不是一个方法吗?我可能不会在CherryPy页面处理程序中创建池。线程和多进程并不总是最好的朋友,因为我最近了解到,我没有正确阅读你最初的帖子。如果你不需要服务器,就这样做:
CherryPy.server.uNSSubscribe()
在快速启动调用之前。好吧,主机需要服务器(*是服务器),但池中的分叉工作程序不需要。我尝试了
pool=pool(initializer=cherrypy.server.unsubscribe)
,没有其他异常!日志中仍然有一些奇怪的错误,将更新问题,请您发表评论。
[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'
[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
import multiprocessing
import os
import time

import cherrypy

def run_in_sub_proc(size):
    for i in range(size):
        print os.getpid(), i
        time.sleep(1)

pool = multiprocessing.Pool(2)

class Root(object):
    @cherrypy.expose
    def index(self):
        pool.map_async(run_in_sub_proc, (3, 5))

if __name__ == '__main__':
    cherrypy.engine.subscribe('stop', pool.join)
    cherrypy.quickstart(Root())