2010-06-25 10 views
6

ben bu kod parçası ile kilitlenme sorunlar yaşıyorum olsun: Ben programı çalıştırdığınızda, _entropy_split_parallel aracılığıyla birkaç koşular için çalışıyorPython multiprocessing.Queue üzerine konur kilitlenmeleri ve


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() 

, ama sonunda kilitlenmeleri. Ana işlem done_queue.get()'da engelleniyor ve çalışan işlem done_queue.put()'da engelleniyor. Bu olduğunda sıra her zaman boş olduğundan, get'da engelleme bekleniyor. Anlamadığım şey, işçinin neden tam olarak dolmadığı (yani boş!) Olduğu için çalışanın neden put üzerinden engellendiği. block ve timeout anahtar kelime bağımsız değişkenlerini denedim, ancak aynı sonucu elde ettim.

Python 2.5 ile sıkıştığım için çok işlemcili arka koltuk kullanıyorum.

DÜZENLEME: Çok işlemcili modülle sağlanan örneklerden biri ile de kilitlenme sorunları alıyorum gibi görünüyor. Alttan here.'un üçüncü örneğidir. Kilitlenme sadece test yöntemini birçok kez çağırırsam ortaya çıkar. Bu eski bir soru olacak ama test bu Python 2.7 ile pencerelerde bir sorun artık olduğunu gösterir:


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

EDIT: Örneğin, bu komut dosyası alt değiştirme. Linux'u deneyeceğim ve rapor edeceğim.

cevap

0

Bu sorun, Python'un daha yeni sürümleriyle birlikte ortadan kalktı, bu yüzden arka taraftaki bir sorun olduğunu varsayıyorum. Her neyse, artık bir sorun değil.

4

Sorun, bir Kuyruktan geçtiği bir alt iş parçacığına katılan üst iş parçacığı olduğunu düşünüyorum. Bu çok işlemcili modülün programming guidelines section.

Her halükarda, tanımladığınız aynı belirtiyle karşılaştım ve mantığımı yeniden düzenlediğimde, ana iş parçacığı alt iş parçacığına katılmadığında, kilitlenme olmadı. Refactored mantığım, sonuçlardan veya "done" kuyruğundan almam gereken öğelerin sayısını bilmeyi (ya da çocuk kuyruğunun sayısına ya da iş kuyruğundaki öğelerin sayısına, vb. Göre tahmin edilebilen) ve döngü oluşturmayı içeriyordu. Bunların hepsi toplanana kadar sonsuz bir şekilde. mantık

"Oyuncak" illüstrasyon:

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) 

yukarıdaki mantık çocuk iplik katılmak için ebeveyn iplik ihtiyacını ortadan kaldırır, henüz tüm çocukların yapılana kadar ana iş parçacığı engellemek için izin verir. Bu yaklaşım benim kilitlenme problemlerimi önledi.

+0

Süreçler birleştirildiğinde tüm sıraların boş olması gerektiğini düşünüyorum, bu nedenle sorun olmamalı. Üstelik, ana işlem, birleştirmek yerine koymak yerine kilitleniyor. Python'u yeni sürüme geçirdim (eski bir sürümle takıldım), bu yüzden tekrar test edeceğim. Benim durumumda – ajduff574

+0

@ajduff, çıkmazda birleşme gerçekleşmedi, ama aynı zamanda koydu, çünkü çocuk ipliğinin içinde olduğu ortaya çıktı. Ayrıca, benim durumumda, konulan sıra boştu. Bu yüzden sizin de durumunuza bir atış (yani, çocuk dişlerini birleştiren ana ipekten kaçınmak) gerektiğini düşünüyorum. – Jeet