«WindowsError: Имя файла или расширение слишком длинное» после запуска программы очень много раз с подпроцессом

Моя программа 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: \. Я подтвердил, что ни один из аргументов для подпроцесса не превышает 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() 

    hmmm …. на самом деле, я думаю, текст сообщения об ошибке – это красная селедка. Я не знаю точно, но мне кажется, что все происходит, когда у вас заканчиваются файловые дескрипторы. Из разных источников кажется, что ограничение канонического файла составляет около 2048 файлов … что любопытно в окрестности 2 x ваших подпроцессов 1042. Я не знаю внутренних компонентов интерпретатора python windows, но я предполагаю, что ручки не собираются слишком быстро собирать мусор, даже если вы закрываете файлы. Опять же … это всего лишь предположение … но, возможно, это еще одна линия мышления, которая может привести вас к чему-то более убедительному и продуктивному.

    Тем временем, как работа, вы можете использовать старый подход «stand-by», имея процесс губернатора, который порождает процесс, который, в свою очередь, порождает подпроцессы. Промежуточный подпроцесс имеет определенный срок службы (скажем … не более 1000 подпроцессов, которые он порождает), прежде чем он умрет. Когда промежуточный подпроцесс истекает, процесс управления начинает новый. Это взлом … и неуклюжий в этом … но он работает. (IIRC, веб-сервер Apache имел какое-то ограничение для самоуничтожения количества запросов, которые может обрабатывать подпроцесс.)

    В любом случае … удачи и счастливого кодирования.