【问题标题】:Python: Forced num processes in multiprocess poolPython:多进程池中的强制进程数
【发布时间】:2013-12-09 17:39:03
【问题描述】:

所以我有两个 python 脚本。第一个是扫描数千个文件的解析器,第二个是在数百个单独目录上分叉扫描的调度程序。我的问题是这样的:

我的磁盘资源有限,每次扫描使用大约 1GB 的本地 sqlite3 存储。我需要限制进程数,以便在运行最大进程数时,不会出现磁盘 IO 错误,这是我一直在得到的。

我尝试使用以下代码来分叉扫描并将进程保持在 8,但是当我查看我的临时目录(存储临时本地文件的位置)时,有超过 8 个文件显示我'没有正确限制进程(我使用 os.remove 在扫描完成后删除临时文件)。

这是我的执行扫描方法,它只是用格式良好的命令分叉一个进程

def execute_scan(cmd):
    try:
        log("Executing "+ str(cmd))
        subprocess.call(cmd, shell=False)
    except Exception as e:
        log(e)
        log(cmd)

这是在我的 main 方法中,getCommand(obj) 将对象中的数据转换为命令数组。

tasks = [getCommand(obj) for obj in scanQueue if getCommand(obj) is not None]   
multiprocessing.Pool(NUM_PROCS).map(execute_scan, tasks)

我可以使用我能得到的任何建议,因为我正在处理大量数据并且我的磁盘并不大。

非常感谢!

【问题讨论】:

  • 我再重复一遍:parallelizing I/O bound tasks leads to worse runtimes than running the tasks in a single thread (or process)。使用多个线程或进程仅在处理 CPU 密集型任务时才有用(即便如此,并非每次都如此)
  • 您没有显示任何删除临时文件的代码,但这可能就是问题所在。查看临时文件以间接推断正在运行的进程数是很奇怪的;-) 使用操作系统工具直接计算进程数。 Pool(NUM_PROCS) 创建完全 NUM_PROCS 进程 - 不多也不少。
  • @TimPeters 正如我在描述中提到的,我使用 os.remove(path) 删除了临时文件,这部分工作正常。
  • @goncalopp 您认为由于 IO 部分的瓶颈,我可以完全避免多处理吗?由于上下文切换开销更少,我会以这种方式获得任何速度吗?
  • @ecesurfer,不过,您没有在上下文中显示代码。只能重复 Pool(NUM_PROCS) 精确创建 NUM_PROCS 进程,计算临时文件不计算进程。换句话说,我不相信你 ;-) 如果你的操作系统显示的进程比这多,那么我可能会。

标签: python multithreading multiprocessing


【解决方案1】:

gevent.pool.Pool 可能是适合您的解决方案。因为gevent使用greenlet做并发操作,一次只能运行一个greenlet。

在您的情况下,首先,将池大小设置为适当的数字,这意味着最多有该数量的 greenlet 可以执行一些 I/O 操作。然后将执行扫描任务的函数变成一个greenlet,并将其添加到由hubgreenlet调度的池中。

这里有一个关于gevent.pool.Pool使用的简单教程

【讨论】:

    【解决方案2】:

    虽然我本可以在这个应用程序上使用多处理,但事实证明,由于 sqlite3 数据库的 IO 是瓶颈,多处理实际上会减慢它的速度,正如 goncalopp 预测的那样。

    【讨论】:

      猜你喜欢
      • 2015-01-13
      • 2017-07-03
      • 2013-12-01
      • 2022-01-08
      • 2013-12-22
      • 2011-10-21
      • 2016-03-02
      • 2018-05-14
      • 1970-01-01
      相关资源
      最近更新 更多