【问题标题】:Too many open files error with Popen of subprocess子进程的Popen打开文件过多错误
【发布时间】:2014-07-10 16:50:15
【问题描述】:

我正在使用 Python 的 subprocess 模块调用命令将值从文件写入内存。它看起来像:

import subprocess

f = open('memdump', 'r')
content = [line.split()[1] for line in f]
f.close()
tbl_pt0 = 0x4400
tbl_pt1 = 0x4800
process = 0
i = 0
for value in content:
    p1 = subprocess.Popen("echo \"jaguar instance=0; jaguar wr offset=0x%x value=%s\" | pdt" \
% (tbl_pt0, value), shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
    p2 = subprocess.Popen("echo \"jaguar instance=0; jaguar wr offset=0x%x value=%s\" | pdt" \
% (tbl_pt1, value), shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
    tbl_pt0 += 0x4
    tbl_pt1 += 0x4

这里的 pdt 是一个写入值的程序。文件中有 256 个值,因此 for 循环运行 256 个循环。但是当我到达循环 253 时,在 subprocess.py 中出现了太多打开的文件错误。任何人有任何想法?谢谢。

【问题讨论】:

  • 不要使用subprocess.PIPE,除非您从相应的管道读/写(在您的示例中没有)。

标签: python file subprocess popen


【解决方案1】:

原因是subprocess.Popen 调用是异步的,因为它会立即返回,而无需等待生成的进程退出。也就是说,您正在快速创建 2x256 进程。它们每个都有 2 个管道,每个管道占用 1 个文件描述符。单个进程可以在任何时候打开有限数量的文件描述符,并且您可以访问它,因为您不等待进程和管道关闭。您可以等待他们退出,例如p.communicate() 其中psubprocess.Popen 的返回值,或者增加一次打开的最大文件描述符:

  • 永久 - 将 fs.file-max = 100000 添加到 /etc/sysctl.conf
  • 暂时(直到重新启动)-sysctl -w fs.file-max=100000

【讨论】:

    【解决方案2】:

    每次 Popen 都会创建 6 个新的文件句柄。也许你可以一个一个地运行这些进程, 并使用 echo 的通信插入:

    import subprocess
    from itertools import count
    
    JAGUAR = "jaguar instance=0; jaguar wr offset=0x%x value=%s"
    
    with open('memdump', 'r') as f:
        content = [line.split()[1] for line in f]
    
    for tbl_pt0, tpl_pt1, value in zip(count(0x4400,4), count(0x4800,4), content):
        subprocess.Popen(["pdt"], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
            close_fds=True).communicate(JAGUAR % (tbl_pt0, value))
        subprocess.Popen(["pdt"], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
            close_fds=True).communicate(JAGUAR % (tbl_pt1, value))
    

    【讨论】:

      猜你喜欢
      • 2017-03-06
      • 2015-05-02
      • 1970-01-01
      • 2021-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-03
      • 2013-05-07
      相关资源
      最近更新 更多