<ol>
<li><p>您正在创建一个托管的<code>List</code>对象,然后让关联的<code>Manager</code>对象过期。</p></li>
<li><p><code>Process</code>对象是可共享的,因为它们不可pickle;也就是说,它们并不简单。</p></li>
<li><p>奇怪的是<code>multiprocessing</code>模块没有<code>threading.enumerate()</code>的等价物——也就是说,您<em>不能</em>列出所有未完成的进程。作为一种解决方法,我只是将进程存储在一个列表中。我从不<code>terminate()</code>进程,而是在父进程中<code>sys.exit(0)</code>。这很难,因为工人们会让事情处于不一致的状态,但对于较小的程序来说是可以的</p></li>
<li><p>要杀死冻结的工作进程,我建议:1)工作进程不时在队列中接收“心跳”作业;2)如果父进程发现工作进程a在一定时间内没有响应心跳,则<code>p.terminate()</code>。考虑在另一个非常有趣的问题中重新说明这个问题。</p></li>
</ol>
<p>老实说,<code>map</code>东西比使用管理器容易得多。</p>
<p>这是我用过的一个经理的例子。工作人员将内容添加到共享列表中。另一个工人偶尔会醒来,处理列表上的所有内容,然后再回去睡觉。代码还具有详细的日志,这些日志对于调试非常重要。</p>
<h2>来源</h2>
<pre><code># producer adds to fixed-sized list; scanner uses them
import logging, multiprocessing, sys, time
def producer(objlist):
'''
add an item to list every sec; ensure fixed size list
'''
logger = multiprocessing.get_logger()
logger.info('start')
while True:
try:
time.sleep(1)
except KeyboardInterrupt:
return
msg = 'ding: {:04d}'.format(int(time.time()) % 10000)
logger.info('put: %s', msg)
del objlist[0]
objlist.append( msg )
def scanner(objlist):
'''
every now and then, run calculation on objlist
'''
logger = multiprocessing.get_logger()
logger.info('start')
while True:
try:
time.sleep(5)
except KeyboardInterrupt:
return
logger.info('items: %s', list(objlist))
def main():
logger = multiprocessing.log_to_stderr(
level=logging.INFO
)
logger.info('setup')
# create fixed-length list, shared between producer & consumer
manager = multiprocessing.Manager()
my_objlist = manager.list( # pylint: disable=E1101
[None] * 10
)
multiprocessing.Process(
target=producer,
args=(my_objlist,),
name='producer',
).start()
multiprocessing.Process(
target=scanner,
args=(my_objlist,),
name='scanner',
).start()
logger.info('running forever')
try:
manager.join() # wait until both workers die
except KeyboardInterrupt:
pass
logger.info('done')
if __name__=='__main__':
main()
</code></pre>