子进程的Popen打开文件太多错误

时间:2014-07-10 16:50:16

标签: python file subprocess popen

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

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中得到了太多的打开文件错误。谁有任何想法?感谢。

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

每个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))