2012-03-17 116 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

相關問題