我的自定义上下文管理器的退出功能似乎在计算完成之前运行。我的上下文管理器旨在简化编写并发/并行代码。这是我的上下文管理器代码:
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__
被如此早地调用?
答案 0 :(得分: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
答案 1 :(得分:0)
最可能的解释是发生了异常。上面的代码示例未解析type
语句的value
,traceback
或__exit__
自变量。因此,发生了一个异常(并且没有更早捕获),该异常被交给了退出语句,而退出语句又对该异常没有反应。进程(或其中一些)继续运行。