2017-12-21 4 views
1

경고 또는 오류없이 Python의 다중 처리 모듈을 사용하여 실행중인 코드가 중단됩니다. 나는 그것이 플롯이 생성 될 때까지 좁혔다 고 생각합니다. 멀티 프로세싱과 matplotlib 사이에 약간의 비 호환성이 있습니까?플로팅 중에 파이썬 다중 프로세싱이 멈 춥니 다

저는 파이썬에서 많은 수의 데이터 세트를 미리 처리하고 있습니다 (numpy, scipy, pandas 사용). 각 데이터 세트는 별도의 데이터 파일 모음으로 구성됩니다. 원시 데이터를 읽고 각 .pkl 파일과 소수의 .png 파일을 각 데이터 세트에 대해 작성합니다. 플롯은 matplotlib 및 seaborn을 사용하여 생성됩니다. 그림은 표시되지 않고 파일로 저장됩니다. 각 데이터 세트의 전처리는 서로 완전히 독립적이어야합니다.

처리가 순차적으로 작동합니다. preprocess.main_debug()는 경로/파일 이름/플래그에 소요 리턴 ('전체가', '생략'등) 상태 문자열 :

import preprocess 

# Serial processing 
dataroot = '/Volumes/ExtData/' 
study = 'study0' 
datasets = ['data0', 'data1', 'data2'] 
force_preprocess = True 
quiet_console = False 

status = [preprocess.main_debug(dataroot, study, dataset, 
           force_preprocess, quiet_console) 
      for dataset in datasets] 

# Print summary 
print('\n---- Summary --------------') 
for d, s in zip(datasets, status): 
    print(' {}:\t{}'.format(d, s)) 

을하지만 다중이 중단 :

import multiprocessing as mp 
import logging 
import preprocess 

dataroot = '/Volumes/ExtData/' 
study = 'study0' 
datasets = ['data0', 'data1', 'data2'] 
force_preprocess = True 
quiet_console = True # Suppress console output 

# Send multiprocessing logs to console 
mp.log_to_stderr() 
logger = mp.get_logger() 
logger.setLevel(logging.INFO) 

# Parallel process 
pool = mp.Pool(processes=3, maxtasksperchild=1) 
results = [pool.apply_async(preprocess.main_debug, 
          args=(dataroot, study, dataset, 
          force_preprocess, quiet_console)) 
      for dataset in datasets] 
status = [p.get(timeout=None) for p in results] 

# Print summary 
print('\n---- Summary --------------') 
for d, s in zip(datasets, status): 
    print(' {}:\t{}'.format(d, s)) 

내가 ' 프로세스의 수, maxtasksperchild 및 시간 초과로 아무런 효과가 없게되었습니다. 로깅과 멀티 프로세싱 사이에 약간의 비호 환성이있을 수 있음을 나타내는 온라인 링크를 찾았으므로 모든 로깅 코드가 제거되었지만 같은 방식으로 실행이 중단됩니다.

코드의 다중 처리 버전을 실행하면 콘솔에 표시됩니다.

$ python batchpreprocess.py 
[INFO/PoolWorker-1] child process calling self.run() 
[INFO/PoolWorker-2] child process calling self.run() 
[INFO/PoolWorker-3] child process calling self.run() 

7 분 정도 지나면 CPU 사용량이 100 %에서 0 %로 감소하고 메모리 사용량이 ~ 12GB에서 ~ 3MB로 줄어 듭니다. 그 다음 3 개의 자식 프로세스가 시작된다는 것을 알 수 있습니다. 물건들은이 상태에 머물러 있습니다 (적어도 밤새도록). 3 개의 데이터 세트로 테스트를했기 때문에 이상하게 보였으므로 3 개의 하위 프로세스 만 합쳐 졌을 것으로 예상됩니다.

$ python batchpreprocess.py 
[INFO/PoolWorker-1] child process calling self.run() 
[INFO/PoolWorker-2] child process calling self.run() 
[INFO/PoolWorker-3] child process calling self.run() 
[INFO/PoolWorker-4] child process calling self.run() 
[INFO/PoolWorker-5] child process calling self.run() 
[INFO/PoolWorker-6] child process calling self.run() 

로깅 구문을 사용하여 코드를 뿌렸습니다. 파형의 플롯을 생성하는 코드를 플로팅하는 곳에서 충돌이 발생합니다. 플롯 팅 코드를 제거하면 그 지점까지 실행이 계속되지만 다음 플롯에서 중단됩니다.

preprocess.main_debug의 내용은()과 같습니다

def main_debug(dataroot, study, dataset, force_preprocess, quiet_console): 
    try: 
     status = main(dataroot, study, dataset, 
         force_preprocess, quiet_console) 
     return status 
    except: 
     print('Problem in dataset {}'.format(dataset)) 
     return 'Exception' 

def main(dataroot, study, dataset, force_preprocess, quiet_console): 
    ... 
    [load files, do signal processing, make plots, save .pkl file] 
    ... 
    return 'Done' 

나는 전처리의 일환으로 만들어진 플롯이 필요합니다. (저장된 pkl 파일에서 플로팅이 가능하지만 대부분의 코드를 다시 실행해야 할 것입니다.) 다른 누군가가 유사한 것을 뛰어 다니며 해결 방법을 알고 있기를 바랍니다.

감사합니다,

데릭

파이썬 2.7, OSX 높은 시에라, 그냥 아나콘다를 사용하여 내 모든 패키지를 업데이트했습니다.

+0

. 데이터 포인트가 너무 많아서 매달려있었습니다. 데이터 세트를 잘라내서 작은 부분 만 그래프로 표시하여 이것이 일어날 수 있는지 알아봐야합니다. –

+0

플로팅 코드가 표시되지 않습니다. 그래서 그것이 매달려있는 곳이 확실한가요? 어떤 백엔드를 사용하고 있습니까? AGG가 아니라면 AGG –

+0

을 시도해보십시오. 어떻게 든 교착 상태에 빠진 것처럼 보입니다. 이는 프로세스가 리소스를 공유하고 일반적으로 멀티 스레딩보다 발생할 가능성이 적은 멀티 프로세싱에서 주로 발생하는 경우에만 발생할 수 있습니다. 귀하의 게시물에서 볼 수있는 것부터 멀티 프로세싱의 모든 설정이 올바른 것처럼 보입니다. 'preprocess.main_debug' 코드를 추가 할 수 있습니까? 아니면 적어도 매개 변수와 함수의 변수 초기 설정? – hansaplast

답변

1

matplotlib에서 대화식 백엔드를 사용하도록 설정 한 경우, 플롯은 주 루프를 종료해야하는 창이 생성됩니다.

이 문제를 방지하려면 "agg"와 같은 비대화 형 백엔드를 사용하십시오.

matplotlibrc 파일에서 매개 변수를 설정할 수 있습니다.또한, pyplot 가져 오는 이전, 당신은 할 수 있습니다

:

내가하기 matplotlib 이제까지 내가 만들려고했던 그래프를 마무리하지 문제를 했어
import matplotlib 
matplotlib.use('agg') 
+0

고마워, 폴. 내 스크립트에서 show()를 호출하지 않았으므로 어떤 창이 나타나기를 기대하지 않았습니다. 그러나 나는 macosx가 변칙적이라는 것에 관한 문서에서 뭔가를 보았습니다. "OSX 창에서 코코아 렌더링 (현재 matplotlib이 비 대화식 모드 일 때 show() 동작을 차단하지 못함)". 아마 그게 관련이 있을지도 몰라. 도움에 다시 한번 감사드립니다. – dereky