2012-02-09 14 views
5

मेरे पास कुछ निर्माता फ़ंक्शन हैं जो I/O भारी अवरुद्ध कॉल और कुछ उपभोक्ता फ़ंक्शंस पर भरोसा करते हैं जो I/O भारी अवरुद्ध कॉल पर भरोसा करते हैं। उन्हें गति देने के लिए, मैंने गीवेंट माइक्रो-थ्रेडिंग लाइब्रेरी का उपयोग गोंद के रूप में किया था।मैं गेवेंट में बहु-उत्पादक, बहु-उपभोक्ता प्रतिमान को कैसे कार्यान्वित कर सकता हूं?

import gevent 
from gevent.queue import * 
import time 
import random 

q = JoinableQueue() 
workers = [] 
producers = [] 

def do_work(wid, value): 
    gevent.sleep(random.randint(0,2)) 
    print 'Task', value, 'done', wid 

def worker(wid): 
    while True: 
     item = q.get() 
     try: 
      print "Got item %s" % item 
      do_work(wid, item) 
     finally: 
      print "No more items" 
      q.task_done() 


def producer(): 
    while True: 
     item = random.randint(1, 11) 
     if item == 10: 
      print "Signal Received" 
      return 
     else: 
      print "Added item %s" % item 
      q.put(item) 



for i in range(4): 
    workers.append(gevent.spawn(worker, random.randint(1, 100000))) 

#This doesnt work. 
for j in range(2): 
    producers.append(gevent.spawn(producer)) 

#Uncommenting this makes this script work. 
#producer() 

q.join() 

मैं चार उपभोक्ता है और दो उत्पादकों करना चाहते हैं:

यहाँ की तरह मेरे प्रतिमान कैसा दिखता है। उत्पादक बाहर निकलने पर बाहर निकलते हैं यानी 10. उपभोक्ता इस कतार को खिलाना जारी रखते हैं और जब उत्पादक और उपभोक्ता खत्म हो जाते हैं तो पूरा कार्य खत्म हो जाता है।

हालांकि, यह काम नहीं करता है। अगर मैं for लूप पर टिप्पणी करता हूं जो एकाधिक उत्पादकों को जन्म देता है और केवल एक निर्माता का उपयोग करता है, तो स्क्रिप्ट ठीक चलती है।

मुझे यह पता लगाना प्रतीत नहीं होता कि मैंने क्या गलत किया है।

कोई विचार?

धन्यवाद

उत्तर

6

कतार में कोई अधूरा काम नहीं होने पर आप वास्तव में बाहर निकलना नहीं चाहते हैं, क्योंकि अवधारणात्मक रूप से यह नहीं है कि एप्लिकेशन कब खत्म होना चाहिए।

उत्पादकों के समाप्त होने पर आप छोड़ना चाहते हैं, और तब जब कोई अधूरा काम नहीं होता है।

# Wait for all producers to finish producing 
gevent.joinall(producers) 
# *Now* we want to make sure there's no unfinished work 
q.join() 
# We don't care about workers. We weren't paying them anything, anyways 
gevent.killall(workers) 
# And, we're done. 
3

मैं इसे q.join() करता है से पहले कुछ भी कतार में रख दिया और तुरंत बाहर निकालता है लगता है। कतार में शामिल होने से पहले सभी उत्पादकों में शामिल होने का प्रयास करें।

+0

हाय Zch, मैं पूरी तरह से अपने जवाब पालन नहीं किया। क्या आप कृपया एक छोटा सा स्निपेट पेस्ट कर सकते हैं? इससे चीजों को थोड़ा सा स्पष्ट किया जाएगा। –

+0

@MridangAgarwalla - निर्माता में निर्माता के लिए 'q.join()' लिखें 'से पहले: producer.join() '। इस तरह आप पहली बार इंतजार करते हैं जब तक सभी निर्माता अपने काम को समाप्त नहीं करते हैं और तब तक कतार खाली नहीं होती है। – zch

+0

आह, शायद मैंने इसे गलत कर दिया है। मैं चाहता था कि मेरे निर्माता और उपभोक्ता एक साथ चल रहे हों यानी उत्पादक कतार में तब तक बढ़ते रहते हैं जब तक कि उपभोक्ता इसे तब तक पूरा नहीं करते जब तक कि सभी कतार वस्तुओं को समाप्त नहीं किया जाता है और निर्माता अब कतार में चीजें जोड़ नहीं रहे हैं। –

0

मुख्य कार्यक्रम को अवरुद्ध करने के लिए आप क्या करना चाहते हैं, जबकि निर्माता और कर्मचारी संवाद करते हैं। कतार पर अवरुद्ध होने तक कतार खाली होने तक प्रतीक्षा होगी और फिर उपज, जो तुरंत हो सकती है। बजाय अपने कार्यक्रम के अंत में इस रखो q.join()

gevent.joinall(producers) 
0

मैं आपके जैसे ही मुद्दों मिले हैं। आपके कोड के साथ मुख्य समस्या यह थी कि आपका निर्माता गीवेंट थ्रेड में पैदा हुआ है जो कार्यकर्ता को तत्काल कार्य नहीं कर सका।

मेरा सुझाव है कि आपको मुख्य प्रक्रिया में producer() चलाएं, जो कि गीवेंट थ्रेड में नहीं आती है जब प्रक्रिया चलती है जो निर्माता को तुरंत मिलती है जो तुरंत कार्य को धक्का दे सकती है।

import gevent 
from gevent.queue import * 
import time 
import random 

q = JoinableQueue() 
workers = [] 
producers = [] 

def do_work(wid, value): 
    gevent.sleep(random.randint(0,2)) 
    print 'Task', value, 'done', wid 

def worker(wid): 
    while True: 
     item = q.get() 
     try: 
      print "Got item %s" % item 
      do_work(wid, item) 
     finally: 
      print "No more items" 
      q.task_done() 


def producer(): 
    while True: 
     item = random.randint(1, 11) 
     if item == 10: 
      print "Signal Received" 
      return 
     else: 
      print "Added item %s" % item 
      q.put(item) 


producer() 

for i in range(4): 
    workers.append(gevent.spawn(worker, random.randint(1, 100000))) 

मेकअप भावना से ऊपर संहिताओं .. :)

संबंधित मुद्दे

 संबंधित मुद्दे