2014-09-09 2 views
0

파이썬에서 하나의리스트에 여러 개의 병렬 프로세스를 작성했습니다. 내 코드입니다 : 그것은이 같은파이썬에서리스트에 병렬 쓰기

global_list = [] 
class MyThread(threading.Thread): 
    ... 
    def run(self): 
    results = self.calculate_results() 

    global_list.extend(results) 


def total_results(): 
    for param in params: 
     t = MyThread(param) 
     t.start() 
    while threading.active_count() > 1: 
     pass 
    return total_results 

나는이 aproach을 좋아하지 않는다 :

  1. 전반적인 글로벌 변수 -> 무엇`TOTAL_RESULTS 함수에 대한 지역 변수를 가지고 할 수있는 방법이 있을까요?
  2. 목록이 반환 될 때 확인하는 방법은 다소 서투른 것처럼 보이지만 표준 방법은 무엇입니까?
+0

현재 코드에서 둘 이상의 스레드에서 공유 메모리 (전역 목록)를 수정 중이며 수정 작업 주위에 뮤텍스/잠금이 필요합니다. – davecom

+0

@davecom : 그것은 직관적이지만 실제로는 사실이 아닙니다. 명시 적 잠금 없이도 여러 스레드에서 목록을 수정할 수 없게하는 Python Global Interpreter Lock이 제공됩니다. –

+0

에 따르면 http://effbot.org/pyfaq/what-kinds-of-global-value-mutation-are-thread-safe.htm '확장'은 원자 적 연산이므로 자물쇠가 필요하지 않습니다. – ProfHase85

답변

1

1 - 결과를 추가 할 모든 노동자의 인스턴스간에 공유 클래스 변수를 사용

class Worker(threading.Thread): 
    results = [] 
    ... 

    def run(self): 
     results = self.calculate_results() 
     Worker.results.extend(results) # extending a list is thread safe 

2 - 사용에 가입() 모든 스레드가 완료 전까지 기다려야하고 약간의 계산 시간을 가질 수 있도록

def total_results(params): 
    # create all workers 
    workers = [Worker(p) for p in params] 

    # start all workers 
    [w.start() for w in workers] 

    # wait for all of them to finish 
    [w.join() for w in workers] 

    #get the result 
    return Worker.results 
1

계산에 CPU가 집중적입니까? 그렇다면 Python에 포함 된 다중 처리 모듈을 살펴보고 사용법이 매우 간편한 Pool 클래스를 제공합니다.이 클래스에 계산 작업을 제공하고 나중에 모든 결과를 얻을 수 있습니다. CPU 시간이 많이 필요하다면 어쨌든 더 빨라질 것입니다. 파이썬이 모든 것을 제대로 처리하지 못하기 때문에 한 프로세스에서 한 번에 하나의 인터프리터 스레드 만 실행할 수 있기 때문입니다. 다중 처리 (Multiprocessing)는 그것을 회피합니다 (그리고 당신의 일을 더 쉽게 해주는 Pool 추상화를 제공합니다). 아, 그리고 정말로 쓰레드를 고수하고 싶다면 멀티 프로세싱은 ThreadPool을 가지고 있습니다.

+0

제 계산이 네트워크를 많이 사용하지 않습니다. 이 경우 성능은 내 관심사가 아니지만 코드 디자인이 좋지 않습니다. – ProfHase85