我有一个Python 2.7脚本,其中存在两个日志处理程序,一个用于文件,一个用于stdout。在入口点脚本中,我通过multiprocessing.Pool.apply_async函数产生了多个进程。然后,在每个单独的过程中,我运行current.futures.ThreadPoolExecutor创建多个线程来完成我的工作。我试图确保进程之间没有任何共享(日志记录除外)。但是,偶尔我会遇到ValueError,“对关闭文件的I / O操作”。在回溯中,这会在创建池时发生在sys.stdout.flush()调用上,就像在Pool(5)中一样。
重要的是要注意,我在下面包含的错误似乎发生在父进程中,甚至在创建子进程之前。
我确实实现了library,我发现它可以将写入同步到一个文件。这似乎使ValueError的一个版本消失了,但是我剩下了另一个似乎与stdout可疑链接的版本(如上所述)。
日志记录设置:
oh = signal.signal(signal.SIGINT, signal.SIG_IGN)
pool = Pool(5)
signal.signal(signal.SIGINT, oh)
try:
for item in items:
pool.apply_async(process_item, (args, item), callback=cb)
pool.close()
sleep_count = 0
while ITEM_COUNT != len(items):
time.sleep(1)
sleep_count += 1
except (KeyboardInterrupt, SystemExit):
LOG.info('Terminating all processes because interrupt was received.')
pool.terminate()
创建池。根据另一个堆栈溢出的建议,将while循环和信号处理程序放置在此处,以允许将control-c捕获在父进程中并终止该池。
with ThreadPoolExecutor(max_workers=10) as pool:
for x in xes:
work = pool.submit(handle_x, args)
workers.append(work)
线程创建:
File “myscript.py", line 153, in create_item_workers
pool = Pool (5)
File "<redacted>/multiprocessing/_ init__.py”, line 232, in
p-fatan
return Pool(processes, initializer, initargs, maxtasksperchild)
File "<redacted>/multiprocessing/pool.py”, line 159, in in
Bh v4
“self._repopulate_pool ()
File "<redacted>/multiprocessing/pool.py”, line 223, in rep
opulate_pool
w.start()
File "<redacted>/multiprocessing/process.py”, line 130, ins
tart
self. popen = Popen(self)
File "<redacted>/multiprocessing/forking.py”, line 127, in _
_init__
sys.stdout. flush ()
File "<redacted>/StringIO.py”, line 256, in flush
_complain_ifclosed (self.closed)
File "<redacted>/StringIO.py”, line 40, in complain_ifclose
a
raise ValueError, "I/O operation on closed file”
ValueError: I/0 operation on closed file
跟踪:
device
有人知道这是否与日志记录机制有关,还是这里根本存在其他错误?