2017-04-05 9 views
-1

exit 내 사용자 지정 컨텍스트 관리자의 기능이 계산이 완료되기 전에 실행됩니다. 내 컨텍스트 관리자는 동시/병렬 코드 작성을 단순화하기위한 것입니다. 여기 내 상황에 맞는 관리자 코드 :계산이 끝나기 전에 컨텍스트 관리자 __exit__ 함수가 실행되는 이유는 무엇입니까?

import time 
from multiprocessing.dummy import Pool, cpu_count 

class managed_pool: 
    '''Simple context manager for multiprocessing.dummy.Pool''' 
    def __init__(self, msg): 
     self.msg = msg 
    def __enter__(self): 
     cores = cpu_count() 
     print 'start concurrent ({0} cores): {1}'.format(cores, self.msg) 
     self.start = time.time() 
     self.pool = Pool(cores) 
     return self.pool 
    def __exit__(self, type_, value, traceback): 
     print 'end concurrent:', self.msg 
     print 'time:', time.time() - self.start 
     self.pool.close() 
     self.pool.join() 

이미 multiprocessing.Pool 대신 multiprocessing.dummy.Pool으로이 스크립트를 시도하고 모든 시간을 실패 할 것 같다.

def read_engine_files(f): 
    engine_input = engineInput() 
    with open(f, 'rb') as f: 
     engine_input.parse_from_string(f.read()) 
    return engine_input 

with managed_pool('load input files') as pool: 
    data = pool.map(read_engine_files, files) 

그래서, read_engine_files의 내부 내가 파일의 이름을 인쇄 : 여기

컨텍스트 관리자를 사용하는 예입니다. __exit__ 함수에서 계산이 완료되고 얼마나 오랜 시간이 걸릴지를 확인할 수 있습니다. 그러나 stdout을 볼 때 계산이 끝나기 전에 __exit__ 메시지가 나타납니다. 마찬가지로, 계산이 완료되기 몇 분 전에. 하지만 htop은 모든 코어가 여전히 사용되고 있다고 말합니다. 다음은 출력 예입니다.

start concurrent (4 cores): load engine input files 
file1.pbin 
file2.pbin 
... 
file16.pbin 
end concurrent: load engine input files 
time: 246.43829298 
file17.pbin 
... 
file45.pbin 

__exit__이 너무 일찍 호출되는 이유는 무엇입니까?

+3

여기서 'read_engine_files'의 코드는 무엇입니까? –

+0

@TomDalton'read_engine_files' 함수에 추가했습니다. 왜 이것이 투표 다운되는 이유를 설명 할 수 있습니까? – jamis

+0

최소한의 예제를 제공하지 않았기 때문에 아마 downvoted 것입니다. 추가 코드를 게시하더라도 이제는 'engineInput()'또는 'engine_input.parse_from_string (f.read())'코드를 볼 수 없습니다. –

답변

1

pool.map()으로 전화 하시겠습니까? 모든 항목이 매핑 될 때까지 차단되어야합니다.

Pool의 비동기식 메소드 중 하나를 호출하는 경우 __exit__()의 순서를 변경하여 문제를 해결할 수 있어야합니다. 요약을하기 전에 풀에 가입하십시오.

def __exit__(self, type_, value, traceback): 
    self.pool.close() 
    self.pool.join() 
    print 'end concurrent:', self.msg 
    print 'time:', time.time() - self.start