2017-11-16 168 views
10

İşlemler arasında görevleri dağıtmak için Python'un çoklu işleme özelliğini kullanıyorum.çoklu işleme.Yalnızca yalnızca Google Cloud'da istenenden daha fazla süreç yumurtlama

basit vaka beklendiği gibi çalışır:

from multiprocessing import Pool 

def evaluate: 
    do_something() 

pool = Pool(processes=N) 
for task in tasks: 
    pool.apply_async(evaluate, (data,)) 

N süreçler kökenli ve bunlar sürekli ben apply_async geçmesine ödevlerde. Şimdi, her biri sayısal olarak ağır bir faaliyete ihtiyaç duyan çok farklı çok karmaşık nesneler olduğum başka bir vakam var. Başlangıçta her bir nesnenin kendi çoklu işlemesini yaratmasına izin verdim.Open işini tamamladığı sırada talebine istinaden, ancak sonunda çok fazla dosya açtığından OSError'a koştum, ancak havuzların toplandıktan sonra çöplerin toplanacağını düşünmüştüm. kullanın. Her halükarda

, ben bu karmaşık nesnelerin her hesaplamaları için aynı Pool paylaşmak için zaten tercih olacağına karar verdik: Artık

from multiprocessing import Pool 

def evaluate: 
    do_something() 

pool = Pool(processes=N) 

class ComplexClass: 

    def work: 
     for task in tasks: 
      self.pool.apply_async(evaluate, (data,)) 

objects = [ComplexClass() for i in range(50)] 

for complex in objects: 
    complex.pool = pool 


while True: 
    for complex in objects: 
     complex.work() 

, benim bilgisayarlardan birinde (OS X üzerinde bu çalıştırdığınızda , Python = 3.4), beklendiği gibi çalışır. N süreçler ortaya çıkar ve her karmaşık nesne görevlerini her biri arasında dağıtır. Ancak, başka bir makinede (Ubuntu, Python = 3.5 çalıştıran Google Cloud örneği) çalıştırdığımda, çok sayıda işlem (>> N) oluşturur ve tüm program çekişme nedeniyle durur. Daha fazla bilgiyi havuzu işaretlerseniz

:

import random 
random_object = random.sample(objects, 1) 
print (random_object.pool.processes) 

>>> N 

Her şey doğru görünüyor. Ama açıkça değil. Herhangi bir fikir neler olabilir?

GÜNCELLEME bazı ek günlüğü eklendi. Ben basitlik için havuz boyutunu 1 olarak ayarlayın. Havuz içerisinde, bir görev tamamlandığında, current_process() 'i çok işlemcili modülün yanı sıra os.getpid() işlevinin pidinden basıyorum. Böyle bir şey olur:

<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122 
<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122 
<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122 
<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122 
... 

Yine, Htop kullanarak aslında aktivite bakarak, ben (çoklu işlem havuzunu paylaşan nesne başına bir) birçok süreçleri bu gibi tüm tüketen CPU döngüsü görüyorum böylece sonuçlanan oluyor ilerleme çok OS çekişme çok yavaş. 5122 ana işlem gibi görünüyor.

+0

'multiprocessing.log_to_stderr (logging.DEBUG)' çağrısını ekleyebilirsiniz, hata ayıklamaya yardımcı olmak için daha fazla günlük yazdırılır. – georgexsh

+0

@georgexsh bir ayıklama yardımcı olmak için, bu ekleme, ama sadece çıkış bunu bu bkz [DEBUG/MainProcess] gönderme kolları için dinleyici ve iplik başlangıç ​​3537 20 0 3624M 250M 32.572 T 0.0 0.4 0: 04,35 piton topluluğu .py [INFO/MainProcess] temp dizin oluşturuldu/tmp/pymp-06sjm3do – TSM

+0

Havuzunuzu korumak için 'if __name__ ==' __main __ ': 'hile kullandığınızı varsayalım? – BlackBear

cevap

0

1) Sorunuz, çalıştırdığınızdan farklı bir kod içeriyor (Söz konusu kod yanlış sözdizimi içeriyor ve hiç çalıştırılamıyor).
2) Çok işlemcili modül, çalışanlarda meydana gelen hatalar için hata işleme/raporlamada son derece kötüdür. Sorun, göstermediğiniz kod için çok olasıdır. Gösterdiğiniz kod (eğer düzeltilmişse) sadece sonsuza kadar çalışacak ve CPU'yu yiyecektir, ancak çok fazla açık dosya veya süreçte hatalara neden olmayacaktır.

İlgili konular