gpt4 book ai didi

python - 如何将多处理与多线程一起使用?

转载 作者:太空狗 更新时间:2023-10-30 03:04:52 27 4
gpt4 key购买 nike

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 = pool.map(fnc, args)
pool.terminate()

但这行不通。即使在更简单的情况下,当我根本不使用池时,

    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() 之后或期间。

fork 的工作进程不会对服务器或端口做任何事情。有没有办法告诉 CherryPy 和/或多处理忽略“服务器位”?我不需要 fnc 中的任何端口或套接字。

我需要它在 OSX + Linux 上工作,使用 Python 2.7.1 和 CherryPy 3.2.2。


进度 1:

根据 Sylvain 的建议,我尝试了 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 产生的,所以它们应该是守护进程,但实际上它们仍然存在杀死 parent 后还活着。


进展 3:

我将 fork (=Pool() 调用)移到请求处理方法之外,但是初始化所有必要的状态(以便工作进程可以看到这个状态)。没有更多的错误或异常。

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

最佳答案

“self”指的是哪种类型的对象?你在什么时候初始化并开始你的 fork 进程?也许多一点代码有助于诊断问题。

好的,这很好用:

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())

关于python - 如何将多处理与多线程一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14222415/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com