2010-01-26 12 views
8

द्वारा अवरुद्ध पायथन प्रक्रिया मैंने एक ऐसी प्रक्रिया स्थापित की है जो आने वाले यूआरएल डाउनलोड करने के लिए कतार पढ़ती है लेकिन जब urllib2 कनेक्शन खोलता है तो सिस्टम लटकता है।urllib2

import urllib2, multiprocessing 
from threading import Thread 
from Queue import Queue 
from multiprocessing import Queue as ProcessQueue, Process 

def download(url): 
    """Download a page from an url. 
    url [str]: url to get. 
    return [unicode]: page downloaded. 
    """ 
    if settings.DEBUG: 
     print u'Downloading %s' % url 
    request = urllib2.Request(url) 
    response = urllib2.urlopen(request) 
    encoding = response.headers['content-type'].split('charset=')[-1] 
    content = unicode(response.read(), encoding) 
    return content 

def downloader(url_queue, page_queue): 
    def _downloader(url_queue, page_queue): 
     while True: 
      try: 
       url = url_queue.get() 
       page_queue.put_nowait({'url': url, 'page': download(url)}) 
      except Exception, err: 
       print u'Error downloading %s' % url 
       raise err 
      finally: 
       url_queue.task_done() 

    ## Init internal workers 
    internal_url_queue = Queue() 
    internal_page_queue = Queue() 
    for num in range(multiprocessing.cpu_count()): 
     worker = Thread(target=_downloader, args=(internal_url_queue, internal_page_queue)) 
     worker.setDaemon(True) 
     worker.start() 

    # Loop waiting closing 
    for url in iter(url_queue.get, 'STOP'): 
     internal_url_queue.put(url) 

    # Wait for closing 
    internal_url_queue.join() 

# Init the queues 
url_queue = ProcessQueue() 
page_queue = ProcessQueue() 

# Init the process 
download_worker = Process(target=downloader, args=(url_queue, page_queue)) 
download_worker.start() 

किसी अन्य मॉड्यूल से मैं यूआरएल जोड़ सकता हूं और जब मैं चाहता हूं कि मैं प्रक्रिया को रोक सकता हूं और प्रक्रिया को बंद कर देता हूं।

import module 

module.url_queue.put('http://foobar1') 
module.url_queue.put('http://foobar2') 
module.url_queue.put('http://foobar3') 
module.url_queue.put('STOP') 
downloader.download_worker.join() 

समस्या यह है कि यह सब अवरुद्ध रहने जब मैं ("प्रतिक्रिया = urllib2.urlopen (अनुरोध)") urlopen का उपयोग करें।

अगर मैं डाउनलोड() फ़ंक्शन को कॉल करता हूं या जब मैं प्रोसेस के बिना केवल थ्रेड का उपयोग करता हूं तो कोई समस्या नहीं होती है।

उत्तर

4

यहां मुद्दा urllib2 नहीं है, लेकिन मल्टीप्रोसेसिंग मॉड्यूल का उपयोग नहीं है। विंडोज के तहत मल्टीप्रोसेसिंग मॉड्यूल का उपयोग करते समय, आपको उस कोड का उपयोग नहीं करना चाहिए जो आपके मॉड्यूल को आयात करते समय तत्काल चलता है - इसके बजाय, चीजों को if __name__=='__main__' ब्लॉक के अंदर मुख्य मॉड्यूल में रखें। "मुख्य मॉड्यूल का सुरक्षित आयात" अनुभाग देखें here

#.... 
def start(): 
    global download_worker 
    download_worker = Process(target=downloader, args=(url_queue, page_queue)) 
    download_worker.start() 

और मुख्य मॉड्यूल में:

import module 
if __name__=='__main__': 
    module.start() 
    module.url_queue.put('http://foobar1') 
    #.... 

क्योंकि आप ऐसा नहीं करते, हर बार उपप्रक्रिया था

अपने कोड के लिए, डाउनलोडर मॉड्यूल में निम्नलिखित यह परिवर्तन करने के शुरू किया कि यह मुख्य कोड फिर से चलाएगा और एक और प्रक्रिया शुरू करेगा, जिससे लटका होगा।

+0

मैं विंडोज का उपयोग नहीं करता हूं लेकिन स्टार्ट() फ़ंक्शन का उपयोग करने के आपके सुझाव को समस्या ठीक होती है। धन्यवाद! – Davmuz