2012-03-17 121 views
4

我正在尝试从django进程执行简单的网络作业(ping)。 Django通过apache的mod_wsgi进行部署。但是代码只在第一次运行时才起作用,在随后的运行中返回以下错误。在django应用程序中启动线程时出现奇怪的错误

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内部产生线程的问题引起的。

回答

1

使用线程,我有同样的问题,最终放弃了和使用线程模块,而不是ThreadPool,现在一切工作只是好,所以我认为这个问题肯定是ThreadPool而不是Python线程。

您可以实现自己的ThreadPool或重复别人做过什么(例如thisthis

1

我想这是因为mod_wsgi。在wsgi应用程序中产生线程或分支并不是一个好主意,因为它可能会干扰Web服务器为应用程序产生工作人员的方式。

也许你可以创建一个热电服务,将派遣你的ping所有服务器...

+0

的平安,是我用来测试的整个事情操作性一个最简单的例子,实际上我需要更复杂的交互。你把整个事情转移到另一个pyro服务的想法是一个好主意,但是还有其他方法吗?可能我可以使用另一个网络服务器,如charrypy或其他?因为我需要管理这个pyro服务,所以它可以扩展并运行它的一个实例是不够的。 – Moonwalker 2012-03-18 00:28:41

+0

如果您禁用创建多个工作者,它应该可以工作(您可以在这里获得更多信息(http://code.google.com/p/modwsgi/wiki/ProcessesAndThreading))。但这仍然是一个糟糕的主意(特别是对于表演)。 – Antoine 2012-03-18 00:45:53

+0

好的,所以我一定会将逻辑转移到另一个pyro服务上,但我应该如何扩展它?应该启动多个服务并手动对它们进行负载平衡? – Moonwalker 2012-03-18 09:52:05

5

这是最有可能使用从threading.Thread内线程池时发生known Python bug

no good solution对于这个问题,只是变通方法一样调用线程下面要使用线程池:

if not hasattr(threading.current_thread(), "_children"): 
    threading.current_thread()._children = weakref.WeakKeyDictionary() 
+0

我不明白这个解决方法。你能否指出我更详细的解释? – Moonwalker 2013-10-18 23:39:38

相关问题