Python 为什么multiprocessing.Process.join()挂起?

Python 为什么multiprocessing.Process.join()挂起?,python,python-2.7,multiprocessing,Python,Python 2.7,Multiprocessing,我以这种方式使用多处理: import multiprocessing as mp def worker(thread_id, tasks, results): tmp_dir = 'temp_for_{}'.format(thread_id) os.makedirs(tmp_dir) try: while not tasks.empty(): data = tasks.get() response = p

我以这种方式使用多处理:

import multiprocessing as mp

def worker(thread_id, tasks, results):
    tmp_dir = 'temp_for_{}'.format(thread_id)
    os.makedirs(tmp_dir)
    try:
        while not tasks.empty():
            data = tasks.get()
            response = process_pdf(data, tmp_dir)
            results.put(response)
    except (KeyboardInterrupt, SystemExit):
        log.info('Interrupt signal received in thread %s.', thread_id)
    except Queue.Empty:
        pass
    except Exception:
        log.error("Unexpected error in %s", thread_id, exc_info=True)
    finally:
        shutil.rmtree(tmp_dir)
        log.info("Thread %s exit", thread_id)

if __name__ == "__main__":
    tasks, results = mp.Queue(), mp.Queue()
    for record in cursor.select(query):
        tasks.put(record)
    manager = mp.Manager()
    workers = [mp.Process(target=worker, args=(i, tasks, results)) for i in xrange(8)]
    for worker in workers:
        worker.start()
    try:
        for worker in workers:
            worker.join()
    except (KeyboardInterrupt, SystemExit):
        log.info('Interrupt signal received in main. Cleaning up main')
    finally:
        log.info('Got %s results. Saving', results.qsize())
        while not results.empty():
            cursor.update_one('documents', 'id', results.get())
        cursor.close()
下面是我运行此代码时的输出:

14:34:04 15/10 INFO: Thread 6 exit
14:34:04 15/10 INFO: Thread 7 exit
14:34:21 15/10 INFO: Thread 3 exit
14:34:24 15/10 INFO: Thread 2 exit
14:34:24 15/10 INFO: Thread 1 exit
14:34:29 15/10 INFO: Thread 5 exit
14:34:36 15/10 INFO: Thread 0 exit
14:35:37 15/10 INFO: Thread 4 exit
然后我在等待一段时间后输入^C,但没有任何进展,并获得以下输出:

^C14:37:16 15/10 INFO: Interrupt signal received in main. Cleaning up main
14:37:16 15/10 INFO: Got 16 results. Saving
我得到了所有线程的回溯:

Process Process-9:
Traceback (most recent call last):
  File "/usr/lib64/python2.7/multiprocessing/process.py", line 261, in _bootstrap
    util._exit_function()
  File "/usr/lib64/python2.7/multiprocessing/util.py", line 328, in _exit_function
    util._exit_function()
  File "/usr/lib64/python2.7/multiprocessing/util.py", line 274, in _run_finalizers
    finalizer()
  File "/usr/lib64/python2.7/multiprocessing/util.py", line 207, in __call__
    res = self._callback(*self._args, **self._kwargs)
  File "/usr/lib64/python2.7/multiprocessing/queues.py", line 218, in _finalize_join
    thread.join()
  File "/usr/lib64/python2.7/threading.py", line 952, in join
    thread.join()
  File "/usr/lib64/python2.7/threading.py", line 340, in wait
    waiter.acquire()
KeyboardInterrupt

为什么要挂这个?如果重要的话,我可以补充说
process\u pdf()
使用
subprocess.Popen()
运行了一些子流程,这非常感谢dano的提示。解决此问题的方法是使用
Manager()
创建队列:

编辑

Tnx呼叫暗影游侠。看起来分派中的异常已修复,现在我们可以使用
多处理.Pool
imap\u无序
并且不需要简单的作业:)但是我还没有尝试过它

如果在调用
worker.join()之前
结果
队列中获取所有内容,问题会消失吗
在所有进程上?离题:您正在手动管理一个工作池,并在此处排队,以执行
多处理。池
imap\u无序的情况下可以为您执行的操作。重新设计以使用它将极大地简化您的代码。@dano它会如何导致此问题?不是JoinableQueue@ElRuso看见您的代码并不完全匹配,因为看起来您并没有将大量数据放入队列中,但这是值得排除的。@ElRuso:是的,这是(许多人中)转向Python 3的原因之一;它修复了与此(、和)相关的几个问题。即使在3.5版本中,
Ctrl-C
的效果仍然很糟糕(worker
KeyboardInterrupt
traceback喷到终端,有时需要两个
Ctrl-C
s才能真正结束),但1-2
Ctrl-C
s总是结束程序(并且
最终
处理程序可以输出部分结果).虽然调度中的异常在2.7.10中已修复,但在所有2.x版本中,锁获取仍然是不可中断的,这是问题的很大一部分。在某些情况下,即使在2.7.10上,我也绝对可以锁定,因为特定线程不会被
SIGINT
中断,其他线程也不会被
join
中断。@ShadowRanger此对话,3 .x中的UndoDeDebug错误和新的<代码>收益率<代码>语法肯定使我再次考虑关于移动到Python 3的问题。
manager = mp.Manager()
tasks, results = manager.Queue(), manager.Queue()