Python 在django应用程序内启动线程时出现奇怪错误
我正在尝试从django进程执行一个简单的网络作业(ping)。Django是通过apache的mod_wsgi部署的。但代码只在第一次运行时工作,在后续运行时返回以下错误Python 在django应用程序内启动线程时出现奇怪错误,python,django,multithreading,apache,mod-wsgi,Python,Django,Multithreading,Apache,Mod Wsgi,我正在尝试从django进程执行一个简单的网络作业(ping)。Django是通过apache的mod_wsgi部署的。但代码只在第一次运行时工作,在后续运行时返回以下错误 Traceback: File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response 111. response = callback(request, *
Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/var/www/propingui/ping/views.py" in ping
32. p = Pool(len(fls))
File "/usr/lib/python2.7/multiprocessing/pool.py" in __init__
674. Pool.__init__(self, processes, initializer, initargs)
File "/usr/lib/python2.7/multiprocessing/pool.py" in __init__
134. self._repopulate_pool()
File "/usr/lib/python2.7/multiprocessing/pool.py" in _repopulate_pool
197. w.start()
File "/usr/lib/python2.7/multiprocessing/dummy/__init__.py" in start
73. self._parent._children[self] = None
Exception Type: AttributeError at /
Exception Value: '_DummyThread' object has no attribute '_children'
代码如下:
from multiprocessing.pool import ThreadPool as Pool
...
def _ping((host, firing_location)):
pinger = Pyro4.Proxy("PYRONAME:" + firing_location)
return pinger.ping(host)
def ping(request):
if request.method == 'POST':
form = PingForm(request.POST)
if form.is_valid():
host = form.cleaned_data['host']
fls = ['g1','a1']
p = Pool(len(fls))
noanswer = False
try:
jobs = p.map(_ping, zip([host]*len(fls), fls) )
except:
jobs = []
...
return ...
我试图用谷歌搜索错误,但什么也没找到,我也不明白问题的确切来源。有趣的是,如果我将ThreadPool更改为多处理池,那么一切都可以正常工作。我认为这是django内部的线程生成问题造成的 我认为这是因为mod_wsgi。在wsgi应用程序中生成线程或分支不是一个好主意,因为它会干扰web服务器为应用程序生成工作线程的方式
也许你可以创建一个pyro服务,将ping发送到所有服务器…使用线程,我也遇到了同样的问题,最终放弃并使用线程模块而不是
线程池
,现在一切都很好,所以我想问题一定是线程池
而不是Python线程
您可以实现自己的ThreadPool
或重用其他人所做的(如或)这很可能是从threading.Thread中使用ThreadPool时发生的错误
对于这个问题,没有好的解决方案
,只有一些变通方法,比如在要使用ThreadPool的线程中调用以下命令:
if not hasattr(threading.current_thread(), "_children"):
threading.current_thread()._children = weakref.WeakKeyDictionary()
ping是一个最简单的例子,我用它来测试整个事情的可操作性,实际上我需要更复杂的交互。你的想法是把整个东西转移到另一个烟火服务是一个好主意,但是有其他的方法吗?也许我可以使用另一个Web服务器,比如charrypy之类的?因为我需要管理pyro服务,这样它就可以扩展并运行一个实例是不够的。如果你禁用创建多个worker,它应该可以工作(你可以获得更多信息)。但这仍然是一个坏主意(特别是对性能而言)。好吧,所以我肯定会将逻辑转移到另一个pyro服务,但我应该如何扩展它?应该启动多个服务并手动进行负载平衡吗?对不起,我从未使用过pyro,我无法向您推荐使其可扩展的最佳方法。也许你可以打开一个新的问题,提供关于pyro服务的更多详细信息,以获取建议……这可能是因为使用了mod_wsgi,但实际上可能是由于多处理模块中的一个bug引起的。当使用外部线程(即在Python外部创建的线程)时,Python会创建一个虚拟线程实例。当存在这样的线程时,似乎多处理模块可能会中断。这不是特定于mod_wsgi的,而是任何在C级创建线程并调用Python的东西。我不理解这种解决方法。你能给我指一下更详细的解释吗?