“WindowsError:[错误206]文件名或扩展名太长”在使用子进程运行程序很多次之后

时间:2012-05-23 17:03:49

标签: python windows subprocess hpc

我的python程序准备输入,运行外部FORTRAN代码,并在Windows HPC 2008环境中处理输出。它工作得很好,除非代码执行1042-1045次之间的外部程序(通常问题早先收敛)。在这些情况下,我得到一个例外:

  

WindowsError:[错误206]文件名或扩展名太长

但是,文件名的路径随着时间的推移而增长。它只是清理目录并再次运行。

以下是代码:

inpF = open(inName)
outF = open(localOutName,'w')
p = subprocess.Popen(pathToExe,shell=False,stdin=inpF,stdout=outF,cwd=runPath)
stdout, stderr = p.communicate()
outF.close()
inpF.close()

pathToExe是一个指向UNC位置的常量字符串(例如\\ server \ shared \ program.exe),stdin是本地驱动器上只读模式的打开文件,stdout是处于写入模式的打开文件本地驱动器,cwd是C:\驱动器上的本地路径。根据{{​​3}},我已经确认子进程的参数都不超过80个字符,即使限制应该是32,768。

我做错了什么?某种程度上积累的东西,只有当我跑了一千次才会成为一个问题。

更新:

为了测试“太多文件打开”假设,我做了一个非常小的例子,它使用不同的可执行文件非常快速地运行。这里的主要区别是stdin和stdout在这里只是空文件,而在前一种情况下,它们都是大文件。在这种情况下,代码在2000次运行时运行良好,而早期的运行在~1042处失败。所以它不只是存在那么多文件。也许有太多大文件打开了?

import subprocess
for i in range(nRuns):
    if not (i % (nRuns/10.0)):
        print('{0:.2}% complete'.format(i/float(nRuns)*100))
    inpF=open('in.txt')
    outF=open('out.txt','w')
    p = subprocess.Popen('isotxsmerge.exe',shell=False,stdin=inpF,
                                 stdout=outF,cwd='.')
    stdout, stderr = p.communicate()
    outF.close()
    inpF.close()

1 个答案:

答案 0 :(得分:4)

实际上,我认为错误消息文本是一个红色的鲱鱼。我不确定,但我觉得发生的事情是你的文件句柄用完了。从各种来源,似乎规范文件句柄限制是大约2048个文件...奇怪的是在你的1042个子进程的2 x附近。我不知道Windows python解释器的内部,但我的猜测是,即使你关闭文件,句柄也不会被垃圾收集得足够快。再一次......这只是一个猜测...但也许这是另一种思路,可能会引导你找到更具决定性和生产力的东西。

与此同时,作为一种解决方法,您可以使用旧的备用方法,通过生成一个生成流程的调控器流程,从而生成子流程。中间子流程在其死亡之前具有确定的寿命(例如,它产生的不超过1000个子流程)。当中间子进程到期时,调控器进程启动一个新进程。这是一个黑客......而且是一个笨拙的......但它确实有效。 (IIRC,apache web服务器曾经对子进程可以处理的请求数量有某种自毁限制。)

无论如何......好运和快乐的编码。