2017-04-16 21 views
10

.Python multiprocessing.Queue() Kuyruk() Böyle basit bir görev var

def worker(queue): 
    while True: 
     try: 
      _ = queue.get_nowait() 
     except Queue.Empty: 
      break 

if __name__ == '__main__': 
    manager = multiprocessing.Manager() 
    # queue = multiprocessing.Queue() 
    queue = manager.Queue() 

    for i in range(5): 
     queue.put(i) 

    processes = [] 

    for i in range(2): 
     proc = multiprocessing.Process(target=worker, args=(queue,)) 
     processes.append(proc) 
     proc.start() 

    for proc in processes: 
     proc.join() 

O multiprocessing.Queue i gerekli tüm çalışmaları yapmak, diğer yandan gibi görünüyor el yönetici(). Queue() 'nın birçok örneğini görüyorum ve gerçekten neye ihtiyacım olduğunu anlayamıyorum. Görünüşe göre Manager(). Queue() bir çeşit proxy nesnesi kullanır, ancak bu amacı anlamıyorum, çünkü çoklu işlem.Queue() herhangi bir proxy nesnesi olmadan aynı işi yapar.

Yani, sorularım geçerli:

() Kuyruk multiprocessing.manager tarafından döndürülen

1) Gerçekten fark multiprocessing.Queue ve nesne arasındaki().?

2) Neye ihtiyacım var? Benim anlayış Ben multiprocessing.Queue() ve multiprocessing.Manager() arasındaki bir ana fark vardır söyleyebilirim yaptıklarından, bu konuda sınırlı olmasına rağmen

+3

Bu yardımcı olabilir. https://code.activestate.com/lists/python-tutor/99586/ –

cevap

8

Kuyruk():.

  • çoklu işlem. Queue() bir nesnedir, çok işlemlidir.Manager() .Sessue(), çok işlemcili.Manager() nesnesi tarafından yönetilen paylaşılan sıraya işaret eden bir adres (proxy) 'dir.
  • bu nedenle, normal çoklu işlem.Queue() nesnelerini Havuz yöntemlerine aktaramazsınız, çünkü bu ürün seçilemez.
  • Üstelik python doc multiprocessing.Queue() kullanırken bu istenmeyen etkileri

bir nesne sıraya alınır Not olabilir çünkü özellikle dikkat söyler, nesne turşu ve Bir arka plan iş parçacığı daha sonra turşu verilerini altta yatan bir boruya akıtır. Bunun biraz şaşırtıcı olduğu, ancak pratik zorluklara yol açmaması gereken bazı sonuçları vardır - eğer gerçekten sizi rahatsız ediyorsa, bunun yerine bir yönetici ile oluşturulmuş bir kuyruk kullanabilirsiniz. Boş bir kuyruğa bir nesne yerleştirdikten sonra, sıra boş() yöntemi yanlış döndürmeden önce boşta olabilir ve get_nowait() öğesi Queue.Empty'yi yükseltmeden dönebilir. Birden çok işlem nesnelerini içeriyorsa, nesnelerin diğer uçtan sıra dışı olarak alınması mümkündür. Bununla birlikte, aynı süreç tarafından kabul edilen nesneler, her zaman birbirine göre beklenen sırada olacaktır. Tüm tampon ürün boru temizlenmemiş kadar bir alt işlem bir sıra ürün koymuştur (ve JoinableQueue.cancel_join_thread kullanmadığı) halinde, yukarıda belirtildiği gibi,

Uyarı, daha sonra bu işlem sona olmaz. Bu, sürece katılmayı denerseniz, sıraya yerleştirilen tüm öğelerin tükendiğinden emin olmadığınız sürece bir çıkmaz alabilirsiniz. Benzer şekilde, eğer çocuk süreci daemonik değilse, anormal olmayan tüm çocuklara katılmaya çalıştığı zaman ebeveyn süreci çıkışa asılabilir. Bir yönetici kullanılarak oluşturulan bir sıranın bu sorunu olmadığını unutmayın. Doğru paylaşılan ile

queue = multiprocessing.Queue() 
def initialize_shared(q): 
    global queue 
    queue=q 

pool= Pool(nb_process,initializer=initialize_shared, initargs(queue,)) 

havuz süreçlerini oluşturur:

global değişken olarak bir kuyruğu ve başlangıçta tüm süreçler şeklinde ayarlayarak Havuz multiprocessing.Queue() kullanmak için bir çözüm yoktur sıralar ancak multiprocessing.Queue() nesnesinin bu kullanım için oluşturulmadığını iddia edebiliriz.

Diğer taraftan, manager.Queue() işlevi, bir alt işlevin normal bir argümanı olarak geçerek havuz alt süreçleri arasında paylaşılabilir.

Bence, çok işlemciyi kullanarak. Manager() .Sessue() her durumda iyidir ve daha az zahmetlidir. Bir yönetici kullanarak bazı dezavantajlar olabilir ama farkında değilim.