2013-10-17 12 views
2

파이썬에서 다중 처리를 사용하는 방법을 배우려고합니다. 이 나는 ​​약 multiprocessing을 읽고, 나는이 같은 일을하려고 : 나는 보로 노이 다이어그램을 생성하는 방법에는 다음 클래스 (부분 코드), 한병렬 처리 - 풀 - 파이썬

을 : 나는를 생성하는

class ImageData:  

    def generate_voronoi_diagram(self, seeds): 
    """ 
    Generate a voronoi diagram with *seeds* seeds 
    :param seeds: the number of seed in the voronoi diagram 
    """ 
    nx = [] 
    ny = [] 
    gs = [] 
    for i in range(seeds): 
     # Generate a cell position 
     pos_x = random.randrange(self.width) 
     pos_y = random.randrange(self.height) 
     nx.append(pos_x) 
     ny.append(pos_y) 

     # Save the f(x,y) data 
     x = Utils.translate(pos_x, 0, self.width, self.range_min, self.range_max) 
     y = Utils.translate(pos_y, 0, self.height, self.range_min, self.range_max) 
     z = Utils.function(x, y) 

     gs.append(z) 

    for y in range(self.height): 
     for x in range(self.width): 
      # Return the Euclidean norm 
      d_min = math.hypot(self.width - 1, self.height - 1) 
      j = -1 
      for i in range(seeds): 
       # The distance from a cell to x, y point being considered 
       d = math.hypot(nx[i] - x, ny[i] - y) 
       if d < d_min: 
        d_min = d 
        j = i 
      self.data[x][y] = gs[j] 

이 이 다이어그램이 많기 때문에 많은 시간을 소비하므로이 문제가 병렬 처리되는 전형적인 문제라고 생각했습니다. 그렇지도에 작동하지 않는 외에,

if __name__ == "__main__": 
    entries = [] 
    seeds = np.random.poisson(100) 
    p = Pool() 
    entry = ImD.ImageData(width, height) 
    res = p.apply_async(entry.generate_voronoi_diagram,(seeds)) 
    entries.append(entry) 
    entry.generate_heat_map_image("ImagesOutput/Entries/EntryX") 

그러나 : 내가 같이, "정상적인"방식에서,이 일을했다 :

if __name__ == "__main__": 
    entries = [] 
    for n in range(images): 
     entry = ImD.ImageData(width, height) 
     entry.generate_voronoi_diagram(seeds) 
     entry.generate_heat_map_image("ImagesOutput/Entries/Entry"+str(n)) 
     entries.append(entry) 

이 병렬화하려고, 나는이 시도 단일 다이어그램을 생성 할 때,이 방법을 N 번 수행해야한다고 지정하는 방법을 알지 못합니다.

도움이 될 것입니다. 감사합니다. .

답변

1
같은 생각 할 수 없습니다받을 수 있습니다

파이썬의 멀티 프로세싱은 메모리를 공유하지 않습니다 (명시 적으로 말하지 않는 한). 즉, 작업 프로세스에서 실행되는 모든 기능의 "부작용"을 볼 수 없습니다. generate_voronoi_diagram 메서드는 부작용 인 entry 값에 데이터를 추가하여 작동합니다. 결과를 보려면 함수의 반환 값으로 다시 전달해야합니다. 이제

def do_voroni(entry, seeds): 
    entry.generate_voronoi_diagram(seeds) 
    return entry 

, 당신이 당신의 작업자 프로세스에서이 기능을 사용할 수 있습니다 :

if __name__ == "__main__": 
    entries = [ImD.ImageData(width, height) for _ in range(images)] 
    seeds = numpy.random.poisson(100, images) # array of values 

    pool = multiprocessing.Pool() 
    for i, e in enumerate(pool.starmap_async(do_voroni, zip(entries, seeds))): 
     e.generate_heat_map_image("ImagesOutput/Entries/Entry{:02d}".format(i)) 

e 값을에

다음은 인수와 리턴 값으로 entry 인스턴스를 처리하는 한 가지 방법이다 루프는 entries 목록의 값에 대한 참조가 아닙니다. 오히려 그것들은 작업자 프로세스 (데이터를 추가 한)로 전달 된 다음 다시 통과 한 해당 개체의 복사본입니다.

+0

Huuum, 감사합니다. 하지만 "AttributeError : 'Pool'객체에 'starmap_async'속성이 없습니다. 그러나 참조를 보면이 방법을 찾을 수 있습니다. – pceccon

+0

그래, 실제로 필자는 파이썬 3을 설치하지 않았다. 왜냐하면 matplotlib와 같이 내가 사용해야 할 다른 것들은 전혀 작동하지 않는 것들을 가지고 있기 때문이다. 다른 방법으로 할 수 있습니까? 게다가, 씨앗은 모든 voronoi 다이어그램에 고유합니다. 이것은 사이트의 수를 나타냅니다. – pceccon

+0

@pceccon : 아,'starmap' 메쏘드는 파이썬 3에만있는 것처럼 보입니다.파이썬 2에서'map_async' 메쏘드를 사용할 수 있지만,'entry'와'seed' 값을 얻기 위해 함수 본문에서 언팩 한 2 튜플을 받아들이도록'do_voroni' 함수를 변경해야합니다 :'' def do_voroni (tup) : 항목, 시드 = tup; ...' – Blckknght

0

내가 잘못 될 수도 있지만 난 당신이

고해상도 = p.apply_async (entry.generate_voronoi_diagram, 씨앗)

res.get 사용한다고 생각합니다 (시간 초과 = 1)

당신에게 피클 형 'instancemethod'

내가 가장 쉬운 방법은

import random 
from multiprocessing import Pool 


class ImageData: 

    def generate_voronoi_diagram(self, seeds): 
     ooxx 

    def generate_heat_map_image(self, path): 
     ooxx 

def allinone(obj, seeds, path): 
    obj.generate_voronoi_diagram(seeds) 
    obj.generate_heat_map_image(path) 

if __name__ == "__main__": 
    entries = [] 
    seeds = random.random() 
    p = Pool() 
    entry = ImageData() 
    res = p.apply_async(allinone, (entry, seeds, 'tmp.txt')) 
    res.get(timeout=1)