par*_*ing 6 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()
Run Code Online (Sandbox Code Playgroud)
pathToExe是一个指向UNC位置的常量字符串(例如\\ server\shared\program.exe),stdin是本地驱动器上只读模式的打开文件,stdout是本地驱动器上处于写入模式的打开文件和cwd是C:\驱动器上的本地路径.根据这个有点相关的帖子,我已经确认子进程的参数都没有超过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()
Run Code Online (Sandbox Code Playgroud)
嗯......实际上,我认为错误消息文本是转移注意力的。我不确定,但在我看来,发生的情况可能是文件句柄用完了。从各种来源来看,规范的文件句柄限制似乎约为 2048 个文件……奇怪的是,这大约是 1042 个子进程的 2 倍。我不知道 Windows python 解释器的内部结构,但我的猜测是,即使您正在关闭文件,句柄的垃圾收集速度也不够快。再说一遍……这只是一个猜测……但也许这是另一种思维方式,可能会引导您得出更具结论性和富有成效的东西。
同时,作为一种解决方法,您可以使用旧的备用方法,通过一个调控器进程来生成一个进程,进而生成子进程。中间子进程在消亡之前有一个确定的生命周期(例如......它生成的子进程不超过 1000 个)。当中间子进程到期时,调控器进程会启动一个新的子进程。这是一种黑客……而且是一种笨拙的黑客……但它确实有效。(IIRC,apache Web 服务器过去对子进程可以处理的请求数量有某种自毁限制。)
不管怎样……祝你好运,编码愉快。
| 归档时间: |
|
| 查看次数: |
5601 次 |
| 最近记录: |