2012-12-29 16 views
5

लक्ष्य: Ubuntu 12.04 अजगर VER: 2.7 GEVENT VER redis से डेटा पॉप (redis से पॉप और फिर कतार में डाल दिया)gevent ब्लॉक redis 'सॉकेट अनुरोध

चल ENV के साथ कुछ greenlet कार्यकर्ता सौदा अंडे : 1.0 RC2 REDIS VER: 2.6.5 REDIS-PY VER: redis से डेटा पॉप 2.7.1

from gevent import monkey; monkey.patch_all() 
import gevent 
from gevent.pool import Group 
from gevent.queue import JoinableQueue 
import redis 

tasks = JoinableQueue() 
task_group = Group() 

def crawler(): 
    while True: 
     if not tasks.empty(): 
      print tasks.get() 
      gevent.sleep() 

task_group.spawn(crawler) 
redis_client = redis.Redis() 
data = redis_client.lpop('test') #<----------Block here 
tasks.put(data) 

प्रयास करें, लेकिन यह blocked..and कोई अपवाद नहीं उठाया ... बस फ्रीज और निकालें स्पॉन विधि, यह काम करेगा .. मुझे लगता है कि क्या हैप pened, कृपया मदद करें! आपको धन्यवाद!

उत्तर

9

गीवेंट सहकारी हल्के प्रक्रियाओं (धागे नहीं) प्रदान करता है। नतीजा यह है कि जब आपके पास कहीं अनंत लूप होता है और शेड्यूलर कभी भी पुन: प्रस्तुत नहीं होता है, तो प्रोग्राम 100% CPU कोर लेने में अवरुद्ध होगा।

आपके उदाहरण में, समस्या यह है कि आपने क्रॉलर लूप को परिभाषित किया है। जाहिर है, जब कार्य खाली होता है तो आपके पास अनंत लूप होता है। और क्योंकि gevent.sleep कॉल (जो आवश्यक उपज ऑपरेशन करेगा) केवल तभी कहा जाता है जब कार्य खाली नहीं होता है, इसका मतलब है कि शेड्यूलर कभी भी पुन: प्रस्तुत नहीं होता है।

ऐसा लगता है कि lpop कमांड पर अवरुद्ध है क्योंकि कनेक्शन Redis क्लाइंट द्वारा देरी हो रही है। घटनाओं का क्रम निम्नानुसार है:

  • कार्य समूह उत्पन्न हुआ है; लेकिन अभी तक कोई ग्रीनलेट निर्धारित नहीं है
  • redis_client बनाया गया है, लेकिन वास्तविक कनेक्शन में देरी होने के बाद से यह I/O उत्पन्न नहीं करता है
  • lpop को कॉल किया जाता है; इस बार कनेक्शन वास्तव में जरूरी है क्योंकि रेडिस क्लाइंट को कनेक्शन और एलपीओपी के जवाब का इंतजार करना पड़ता है; यह इसलिए, अनुसूचक
  • अनुसूचक एक क्रॉलर कार्यकर्ता
  • अनंत लूप को सक्रिय करता है करने के लिए पैदावार के बाद से कार्य कतार अभी भी खाली

है आप (के बाद पाश अपने आप में gevent.sleep() डाल दिया अगर), यह बेहतर काम करेगा, लेकिन यह अभी भी एक dequeuer लागू करने के लिए एक अक्षम तरीका है। कुछ इस तरह ज्यादा बेहतर होगा:

def crawler(): 
    while True: 
     x = tasks.get() 
     try: 
      print "Crawler: ",x 
     finally: 
      tasks.task_done() 

प्राप्त() कॉल कार्यकर्ता ब्लॉक कर रहा है, तो यह जबकि कतार खाली है कार्यकर्ता और अनुसूचक के बीच पिंग पांग खेल से दूर रहेंगे।

+0

यह डाउनवॉटेड क्यों है? – schlamar

+0

मुझे नहीं पता लेकिन मैं अभी भी अपने उत्तर से खड़ा हूं ;-) –