2010-06-25 11 views
6

मैं कोड के इस टुकड़े के साथ गतिरोध समस्या आ रही है मिलती है:पुट पर पायथन multiprocessing.Queue गतिरोध और


def _entropy_split_parallel(data_train, answers_train, weights): 
    CPUS = 1 #multiprocessing.cpu_count() 
    NUMBER_TASKS = len(data_train[0]) 
    processes = [] 

    multi_list = zip(data_train, answers_train, weights) 

    task_queue = multiprocessing.Queue() 
    done_queue = multiprocessing.Queue() 

    for feature_index in xrange(NUMBER_TASKS): 
     task_queue.put(feature_index) 

    for i in xrange(CPUS): 
     process = multiprocessing.Process(target=_worker, 
       args=(multi_list, task_queue, done_queue)) 
     processes.append(process) 
     process.start() 

    min_entropy = None 
    best_feature = None 
    best_split = None 
    for i in xrange(NUMBER_TASKS): 
     entropy, feature, split = done_queue.get() 
     if (entropy < min_entropy or min_entropy == None) and entropy != None: 
      best_feature = feature 
      best_split = split 

    for i in xrange(CPUS): 
     task_queue.put('STOP') 

    for process in processes: 
     process.join() 

    return best_feature, best_split 


def _worker(multi_list, task_queue, done_queue): 
    feature_index = task_queue.get() 
    while feature_index != 'STOP': 
     result = _entropy_split3(multi_list, feature_index) 
     done_queue.put(result) 
     feature_index = task_queue.get() 

जब मैं अपने कार्यक्रम चलाने के लिए, यह _entropy_split_parallel के माध्यम से कई रन के लिए ठीक काम करता है, लेकिन अंत में गतिरोध। मूल प्रक्रिया done_queue.get() पर अवरुद्ध हो रही है, और कार्यकर्ता प्रक्रिया done_queue.put() पर अवरुद्ध हो रही है। चूंकि ऐसा होता है जब कतार हमेशा खाली होती है, get पर अवरुद्ध होने की उम्मीद है। मुझे समझ में नहीं आता है कि क्यों कार्यकर्ता put पर अवरुद्ध कर रहा है, क्योंकि कतार स्पष्ट रूप से पूर्ण नहीं है (यह खाली है!)। मैंने block और timeout कीवर्ड तर्कों का प्रयास किया है, लेकिन एक ही परिणाम प्राप्त करें।

मैं मल्टीप्रोसेसिंग बैकपोर्ट का उपयोग कर रहा हूं, क्योंकि मैं पाइथन 2.5 के साथ फंस गया हूं।


संपादित करें: ऐसा लगता है कि मैं भी बहु मॉड्यूल के साथ दिए गए उदाहरणों में से एक के साथ गतिरोध मुद्दों हो रही है। यह नीचे here. से तीसरा उदाहरण है, अगर मैं परीक्षण विधि को कई बार कॉल करता हूं तो डेडलॉकिंग केवल तब होती है। उदाहरण के लिए, यह करने के लिए स्क्रिप्ट के नीचे बदल रहा है:


if __name__ == '__main__': 
    freeze_support() 
    for x in xrange(1000): 
     test() 

संपादित करें: मैं जानता हूँ कि यह एक पुराने सवाल है, लेकिन परीक्षण से पता चलता है कि इस नहीं रह गया है अजगर 2.7 के साथ खिड़कियों पर एक समस्या है। मैं लिनक्स की कोशिश करूंगा और वापस रिपोर्ट करूंगा।

उत्तर

0

यह समस्या पायथन के नए संस्करणों के साथ चली गई, इसलिए मुझे लगता है कि यह बैकपोर्ट के साथ एक समस्या थी। वैसे भी, यह अब कोई मुद्दा नहीं है।

4

मुझे लगता है कि समस्या एक बच्चे धागे में शामिल होने वाला मूल धागा है जिस पर उसने एक कतार पारित की है। इस पर मल्टीप्रोसेसिंग मॉड्यूल के programming guidelines section पर चर्चा की गई है।

किसी भी दर पर, मुझे आपके द्वारा वर्णित वही लक्षण का सामना करना पड़ा, और जब मैंने अपने तर्क को दोबारा सुधार दिया ताकि मास्टर थ्रेड बाल धागे में शामिल न हो, तो कोई डेडलॉक नहीं था। मेरे रिफैक्टर लॉजिक में उन वस्तुओं की संख्या जानने के लिए शामिल हैं जिन्हें मुझे परिणाम या "पूर्ण" कतार से प्राप्त किया जाना चाहिए (जिसे बाल धागे की संख्या या कार्य कतार आदि पर वस्तुओं की संख्या के आधार पर भविष्यवाणी की जा सकती है), और लूपिंग अनन्तकाल तक इन सभी को एकत्रित किया गया था।

"खिलौना" तर्क का चित्रण:

num_items_expected = figure_it_out(work_queue, num_threads) 
items_received = [] 
while len(items_received) < num_items_expected: 
    items_received.append(done_queue.get()) 
    time.sleep(5) 

ऊपर तर्क माता पिता धागा बच्चे धागा शामिल होने के लिए के लिए की जरूरत से बचा जाता है, फिर भी जब तक सभी बच्चों को किया जाता है माता पिता धागा ब्लॉक करने के लिए अनुमति देता है। इस दृष्टिकोण ने मेरी डेडलॉक समस्याओं से परहेज किया।

+0

मुझे लगता है कि प्रक्रियाओं में शामिल होने पर सभी कतार खाली होनी चाहिए, इसलिए यह कोई समस्या नहीं होनी चाहिए। इसके अलावा, मास्टर प्रक्रिया में शामिल होने के बजाय, डालने पर डेडलॉकिंग है। मैंने अभी पायथन को अपग्रेड किया है (मैं पुराने संस्करण के साथ फंस गया था), इसलिए मैं इसे फिर से जांचूंगा। – ajduff574

+0

@ajduff मेरे मामले में, शामिल होने पर डेडलॉक नहीं हुआ था, लेकिन यह भी छोड़ दिया गया कि सिवाय इसके कि बच्चे को बच्चे के धागे में रखा गया था। इसके अलावा, मेरे मामले में, कतार में रखा जा रहा था खाली था। तो मुझे लगता है कि यह आपके मामले में एक शॉट के लायक है (यानी, मास्टर थ्रेड में शामिल होने वाले मास्टर थ्रेड से बचें)। – Jeet