2012-05-23 36 views
6

Il mio programma python prepara gli input, esegue un codice FORTRAN esterno ed elabora le uscite in un ambiente HPC 2008 di Windows. Funziona alla grande, a meno che il codice esegua il programma esterno tra 1042-1045 volte (di solito il problema converge prima). In queste situazioni, ottengo un'eccezione:"WindowsError: [Errore 206] Il nome file o l'estensione è troppo lungo" dopo aver eseguito un programma molte volte con sottoprocesso

WindowsError: [Error 206] The filename or extension is too long

Tuttavia, il percorso del file è non crescere con il tempo. Sta solo pulendo la directory e sta funzionando di nuovo.

Ecco il codice:

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 è una stringa costante punta a un percorso UNC (ad esempio \\ server \ shared \ program.exe), stdin è un file aperto in modalità di sola lettura su un unità locale, stdout è un file aperto in modalità scrittura su un'unità locale e cwd è un percorso locale sull'unità C: \. Ho confermato che nessuno degli argomenti per il sottoprocesso è più lungo di 80 caratteri, anche se il limite dovrebbe essere 32.768, in base a this somewhat related post.

Cosa sto sbagliando? In qualche modo qualcosa si sta accumulando che diventa un problema solo quando corro più di mille volte.

UPDATE:

Per verificare l'ipotesi "troppi file aperti", ho fatto un piccolo esempio che gira molto velocemente con un eseguibile diverso. La differenza principale qui è che stdin e stdout sono solo file vuoti qui, mentre nel caso precedente sono entrambi file di grandi dimensioni. In questo caso, il codice viene eseguito correttamente per 2000 esecuzioni, mentre il precedente non riesce a ~ 1042. Quindi non è solo che ci sono molti file. Forse ci sono troppi file di grandi dimensioni aperti?

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() 

risposta

4

hmmm .... in realtà, penso che il testo del messaggio di errore sia un'aringa rossa. Non lo so per certo, ma mi sembra probabile che quello che sta succedendo sia che stai esaurendo gli handle di file. Da varie fonti, sembra che il limite di handle di file canonici sia intorno a 2048 file ... che è curiosamente nelle vicinanze di 2 x tuoi sottoprocessi 1042. Non conosco le parti interne dell'interprete Python di Windows, ma la mia ipotesi è che gli handle non vengano raccolti in modo sufficientemente veloce, anche se si stanno chiudendo i file. Ancora una volta ... questa è solo una supposizione ... ma forse è un'altra linea di pensiero che potrebbe portarti a qualcosa di più decisivo e produttivo.

Nel frattempo, come soluzione, è possibile utilizzare il vecchio approccio in stand-by con un processo del governatore che genera un processo, che a sua volta genera i sottoprocessi. Il sottoprocesso intermedio ha una durata determinata (ad esempio ... non più di 1000 sottoprocessi che genera) prima che muoia. Quando il sottoprocesso intermedio termina, il processo del governatore ne avvia uno nuovo. Questo è un hack ... e uno maldestro per quello ... ma funziona. (IIRC, il server web Apache utilizzato per avere un qualche tipo di limite di autodistruzione sul numero di richieste che un sottoprocesso potrebbe gestire.)

Comunque ... buona fortuna e buona programmazione.

+0

Grazie. Scommetto che hai ragione che è un'aringa rossa. Ho testato l'ipotesi del numero di file (vedi aggiornamento sopra) e non è stato possibile riprodurre il problema con semplice vuoto stdin/stdouts. Non proprio conclusivo. – partofthething