python

2012-06-19 11 views
5

Çoklu işlem yaparken global değişkeni değiştirme Sonunda ne yapmaya çalıştığım bir satır okuyor, bu satırdaki bilgilerle bazı hesaplamalar yapıyor, sonra sonucu bazı genel nesnelere ekliyor, ama asla elde edemiyorum çalışmak. Örneğin, aşağıdaki kodda test her zaman 0'dır. Bunun yanlış olduğunu biliyorum ve bunu başka yollarla yapmaya çalıştım ama hala çalışmıyor.python

import multiprocessing as mp 

File = 'HGDP_FinalReport_Forward.txt' 
#short_file = open(File) 
test = 0 

def pro(temp_line): 
    global test 
    temp_line = temp_line.strip().split() 
    test = test + 1 
    return len(temp_line) 

if __name__ == "__main__": 
    with open("HGDP_FinalReport_Forward.txt") as lines: 
     pool = mp.Pool(processes = 10) 
     t = pool.map(pro,lines.readlines()) 
+2

Globaller genellikle yanlış bir şey yapıyorsun bir göstergesidir. Programınızın onları engellemek için çalışma şeklini değiştirmenizi öneriyorum - uzun vadede baş ağrılarından kurtulacak ve her zaman daha iyi bir yol olacaktır. –

+0

Çok işlemcili modülün amacı, aynı işlemdeki iş parçacıklarından ziyade çocuk işlemlerini, her zamanki alışkanlıklarla ortaya çıkarmasıdır. Ne yazık ki, belgeler zaten bunları bildiğinizi varsayarak, bu tradeoffları açıklamıyor. Dokümantasyondaki "Programlama yönergeleri" nin tamamını uygularsanız, anlamadan uzaklaşabilirsiniz, ama gerçekten öğrenmelisiniz. – abarnert

cevap

15

Havuzun oluşturduğu işçi işlemleri, genel değişkenin kendi kopyasını alır ve bunu güncelleştirir. Bunu açık bir şekilde ayarlamadıkça bellek paylaşmıyorlar. En kolay çözüm, test son değerini ana işleme geri çağırmaktır, örn. dönüş değeri ile. Böyle bir şey (denenmemiş): Burada

def pro(temp_line): 
    test = 0 
    temp_line = temp_line.strip().split() 
    test = test + 1 
    return test, len(temp_line) 

if __name__ == "__main__": 
    with open("somefile.txt") as lines: 
     pool = mp.Pool(processes = 10) 
     tests_and_t = pool.map(pro,lines.readlines()) 
     tests, t = zip(*test_and_t) 
     test = sum(tests) 
+8

Burada önemli olan, "çoklu işlem" kullanarak iş parçacığının (kuyular, işlemler) durumu paylaşmamasıdır. Yanıt için –

+2

+1 ve +1 @Lattyware. Çok işlemcili belgelerin "iş parçacığı modülüne benzeyen bir API kullanarak yumurtlama işlemlerinin" "iş parçacığı oluşturma" işleminden nasıl farklı olduğunun daha iyi anlaşılmasını dilerim, çünkü bu durum, modüldeki sorunların yarısını çözebilirdi, çünkü… – abarnert

+0

Harika şeyler! Django modellerini güncellememde bana yardımcı oldu. Görünüşe göre bağlantı çatallanmamış ve başka bir işlem tarafından uygunsuz bir şekilde kapatılabilir. Bu yaklaşımı kullandım, ancak zip kullanmamıştım, sadece bir for döngüsü kullanarak tuple elemanlarını listeden girdim ve tuple_element [index] kullanarak tuple'a giden her liste öğesi için. – radtek

0

çoklu işlem içinde genel değişken kullanılırken örnekleri olduğunu.

Biz her işlem değişkeninin kendi kopyasıyla birlikte çalıştığını açıkça görebilirsiniz:

import multiprocessing 
import time 
import os 
import sys 
import random 
def worker(a): 
    oldValue = get() 
    set(random.randint(0, 100)) 
    sys.stderr.write(' '.join([str(os.getpid()), str(a), 'old:', str(oldValue), 'new:', str(get()), '\n'])) 

def get(): 
    global globalVariable 
    return globalVariable 

globalVariable = -1 
def set(v): 
    global globalVariable 
    globalVariable = v 

print get() 
set(-2) 
print get() 

processPool = multiprocessing.Pool(5) 
results = processPool.map(worker, range(15)) 

Çıktı:

27094 0 old: -2 new: 2 
27094 1 old: 2 new: 95 
27094 2 old: 95 new: 20 
27094 3 old: 20 new: 54 
27098 4 old: -2 new: 80 
27098 6 old: 80 new: 62 
27095 5 old: -2 new: 100 
27094 7 old: 54 new: 23 
27098 8 old: 62 new: 67 
27098 10 old: 67 new: 22 
27098 11 old: 22 new: 85 
27095 9 old: 100 new: 32 
27094 12 old: 23 new: 65 
27098 13 old: 85 new: 60 
27095 14 old: 32 new: 71