Python 在django应用程序内启动线程时出现奇怪错误

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, *

我正在尝试从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内部的线程生成问题造成的

我认为这是因为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的东西。我不理解这种解决方法。你能给我指一下更详细的解释吗?