我正在尝试从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, *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中产生线程的问题而引起的。
答案 0 :(得分:5)
当在threading.Thread中使用ThreadPool时,很可能发生known Python bug。
此问题有no good solution
,只是在您想要使用ThreadPool的线程中调用以下内容的解决方法:
if not hasattr(threading.current_thread(), "_children"):
threading.current_thread()._children = weakref.WeakKeyDictionary()
答案 1 :(得分:1)
我认为这是因为mod_wsgi。在wsgi应用程序中生成线程或分叉不是一个好主意,因为它可能会干扰Web服务器为应用程序生成工作者的方式。
也许你可以创建一个pyro服务,将你的ping命令发送到所有服务器......
答案 2 :(得分:1)