九州体育网 - 十年信誉网站

关于作者

Discuss / Python / Pool 为什么要先close再join

Pool 为什么要先close再join

Topic source

苏生不语_

#1 Created at ...
def join(self):
    util.debug('joining pool')
    assert self._state in (CLOSE, TERMINATE)
    self._worker_handler.join()
    self._task_handler.join()
    self._result_handler.join()
    for p in self._pool:
        p.join()

虽然看了源码,join函数里面加了断言 线程的状态必须是 关闭或者终止状态,但是还是不明白为什么要这么做

Champhy_Who

#2 Created at ...

我想主要是为了收回进程池吧。 个人见解

Champhy_Who

#3 Created at ...

负疚之前没解释对 现在我们照搬源代码,做两组实验 你的问题是实验二,直接看最下面即可。 一:保存close,删掉join 会出现两种情况 出现两种情况的原因在于并发主进程和子进程的处理速度差别 一.1

Parent process 79890. Waiting for all subprocessed done... All subprocessed done.

一.2

Parent process 79895. Waiting for all subprocessed done... All subprocessed done. Run task 0 (79896)... Run task 1 (79897)... Run task 2 (79898)...

请多run几次脚本,直到一.2出现 从一.2可知 主进程执行完了,但子进程还在继续。 这里其实是速度的差别造成,换句话说task 0 1 2在主进程跑完前就执行了 那为什么3 4task没有跑,因为进程池closed不再接受新的任务了。这里区别terminate()。 这里可以比方为店铺打烊前,0 1 2三位顾客关门前,跑了进来。而3 4两位顾客腿脚不利索,没进来。 close的情况下, 0 1 2进来了就算了,有饭吃。 teminate的情况,0 1 2进来了也没用,没饭吃。

这里也就是解释了为什么出现一.1的情况,也就是子进程一个都没有跑的比主进程快(笑 那如果想让0 1 2 3 4task都执行,只能让主进程暂停一下,也就是阻塞,也就是p.join()

二.保存join,删除close

ValueError: Pool is still running

join()是主进程阻塞等待子进程的退出. 也就是说join()触发的前提就是 close或terminate了。属于机制问题。


  • 1

Reply

WARNING: You are using an old browser that does not support HTML5. Please choose a modern browser (Chrome / Microsoft Edge / Firefox / Sarafi) to get a good experience.