2014-10-16 7 views
1

저는 멀티 스레딩을 처음 접했습니다. 내 파이썬 스크립트에서 2 기능이 있습니다. 하나의 함수 enqueue_tasks은 큰 항목의 작은 항목을 반복하고 항목을 목록에 추가하는 작업을 수행합니다 (master_list). 이것은 이미 미래를 사용하는 멀티 스레드입니다.두 개의 다중 스레드 기능을 동시에 실행할 수 있습니까?

executor = concurrent.futures.ThreadPoolExecutor(15) # Arbitrarily 15 
futures = [executor.submit(enqueue_tasks, group) for group in grouper(key_list, 50)] 
concurrent.futures.wait(futures) 

는 I는 어떤 동작을 수행 위 master_list을 반복하고이 목록 내의 각 아이템의 상태를 확인하는 다른 함수 process_master있다.

위의 동일한 방법을 사용하여 process_master에 멀티 스레딩을 사용할 수 있습니까? 또한 enqueue_tasks과 동시에 실행할 수 있습니까? 이것의 함의는 무엇입니까? process_masterenqueue_tasks의 목록에 따라 다르므로 동시에 실행해도 문제가되지 않습니까? 두 번째 함수를 약간 지연시킬 수있는 방법이 있습니까? (아마도 time.sleep을 사용)?

답변

1

아니요, 이것은 안전하지 않습니다. enqueue_tasksprocess_master이 동시에 실행중인 경우 process_master이 반복 될 때 enqueue_tasks 안에 master_list 내부에 항목을 추가 할 가능성이 있습니다. iterable을 반복하면서 크기를 변경하면 Python에서 정의되지 않은 동작이 발생하므로 항상 피해야합니다. master_list에 항목을 추가하는 코드와 master_list을 반복하는 코드를 보호하기 위해 threading.Lock을 사용하여 동시에 실행하지 않도록해야합니다.

스레드 안전 형 데이터 구조 인 list 대신 (queue.Queue, Python 3.x)을 사용하십시오. Queueenqueue_tasks의 항목을 추가하고 Queueget 항목을 process_master에 추가합니다. 그런 식으로 process_masterenqueue_tasks과 같은 시간에 안전하게 실행할 수 있습니다.

+0

Ah Queue.Queue가 정말 멋지다. 그렇다면 수동 잠금 메커니즘을 구현할 필요가 없다. 또한 한 스크립트에서 두 개의 다중 스레드 작업을 사용하는 경우 스레드 수를 어떻게 선택해야합니까? 여기서 임의로 15 점을 선택했는데 2 점의 프로세스가 실행 중이면 각각 7 점을해야합니까? 내 논리가 결함이 있니? – jeffrey

+1

@jeffrey 오른쪽,'Queue.Queue'는 잠금이 필요 없습니다. 선택해야하는 쓰레드의 수 (그리고'ThreadPoolExecutor' 나'ProcessPoolExecutor'를 사용해야하는지의 여부)는'enqueue_tasks'와'process_master'에서 당신이하고있는 일에 달려 있습니다. CPU와 관련된 작업을한다면,'ProcessPoolExecutor','multiprocessing.Queue','multiprocessing.cpu_count()'프로세스를 사용해야합니다. – dano

+1

@jeffrey 글로벌 인터프리터 잠금 (GIL) 때문에 한 번에 하나의 파이썬 스레드 만 실행할 수 있으므로 CPU 바인딩 작업을 수행하는 경우 멀티 스레딩의 성능 이점을 얻지 못합니다. 스레드 대신 여러 프로세스를 사용하면 GIL의 한계를 극복 할 수 있습니다. GIL은 I/O를 차단하는 동안 해제 될 수 있으므로 스레드는 여전히 유용합니다. – dano

관련 문제