Python多进程池,等待进程并重新启动自定义进程。

8
我使用了Python的多进程并使用以下代码等待所有进程完成:
```python ```
请注意,保留了HTML标记。
...
            results = []
            for i in range(num_extract):
                url = queue.get(timeout=5)
                try:
                    print "START PROCESS!"
                    result = pool.apply_async(process, [host,url],callback=callback)
                    results.append(result)
                except Exception,e:

                    continue


            for r in results:
                r.get(timeout=7)
...

我尝试使用pool.join但是出现错误:

Traceback (most recent call last):
  File "C:\workspace\sdl\lxchg\walker4.py", line 163, in <module>
    pool.join()
  File "C:\Python25\Lib\site-packages\multiprocessing\pool.py", line 338, in joi
n
    assert self._state in (CLOSE, TERMINATE)
AssertionError

为什么加入不起作用?等待所有进程的好方法是什么。

我的第二个问题是如何重新启动池中的某些进程?我需要这个来解决内存泄漏的问题。现在实际上我在所有进程完成任务后重建整个池(创建新对象池以重新启动进程)。

我需要的是:例如,我有4个进程在池中。然后进程获取它的任务,任务完成后我需要杀死进程并启动新进程(以刷新内存泄漏)。


1
为什么multiprocessing/pool.py存放在site-packages而不是直接存放在Lib中?如果您一直在对其进行修改,那么我们需要知道。 - aaronasterling
嗯...我不知道,我是用Windows安装程序安装的...从官方网站获取的。 - Evg
1个回答

20
您之所以出现该错误,是因为在调用 pool.join() 之前需要调用 pool.close()
我不知道有没有好的方法可以关闭使用 apply_async 启动的进程,但请尝试正确关闭进程池是否可以消除您的内存泄漏问题。
我认为原因是 Pool 类具有许多作为守护程序模式运行的线程属性。所有这些线程都将由 join 方法清理。现有的代码不会清理它们,因此如果创建一个新的 Pool ,您仍将拥有来自上一个进程池中的所有线程。

关于进程池,我的意思是似乎在启动到结束时都使用进程创建池。我的脚本长时间工作,随着时间的推移,池中的所有进程开始在内存中增长,我想从时间到时间重置进程的内存使用情况(每个新任务为进程)。重新启动进程是我可以做到的一种方法。 - Evg
抱歉,我的意思不是内存泄漏,而是关于进程内存简单增长并通过进程重启来控制这种增长的问题。 - Evg
如果新进程能够完成与旧进程相同的任务,但使用的内存更少,那么似乎您在进程本身而不是池中存在内存泄漏。这是一个单独的问题。简要地说,您需要检查是否在进程中创建了任何循环。如果是这样,请确保在使用完它们后删除循环的成员,以便垃圾收集器可以回收空间。 - aaronasterling
我的池子开始有4个进程,每个进程在启动时消耗了近2MB的内存。每个进程执行数千个任务后,它将增长到100MB。这就是为什么我需要为每个新任务重新启动的原因。 - Evg
@Evg. 你所描述的是一个内存泄漏的典型例子。重新启动进程只会掩盖它,而不能解决它。修复进程中的内存泄漏问题,你就不会再有这个问题了。 - aaronasterling
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接