Sto riscontrando un problema interessante con i thread e il modulo tempfile in Python. Sembra che non si stia pulendo qualcosa fino all'uscita dai thread e sto correndo contro un limite di file aperti. (Questo è su OS X 10.5.8, Python 2.5.1.)Python tempfile module e thread non stanno giocando bene; Che cosa sto facendo di sbagliato?
Tuttavia, se riesco a replicare ciò che sta facendo il modulo tempfile (non tutti i controlli di sicurezza, ma solo la generazione di un descrittore di file e quindi l'utilizzo di os. fdopen per produrre un oggetto file) Non ho problemi.
Prima di archiviare questo come un bug con Python, ho pensato di controllare qui, poiché è molto più probabile che sto facendo qualcosa di leggermente sbagliato. Ma se lo sono, un giorno in cui provo a capirlo non mi ha portato da nessuna parte.
#!/usr/bin/python
import threading
import thread
import tempfile
import os
import time
import sys
NUM_THREADS = 10000
def worker_tempfile():
tempfd, tempfn = tempfile.mkstemp()
tempobj = os.fdopen(tempfd, 'wb')
tempobj.write('hello, world')
tempobj.close()
os.remove(tempfn)
time.sleep(10)
def worker_notempfile(index):
tempfn = str(index) + '.txt'
# The values I'm passing os.open may be different than tempfile.mkstemp
# uses, but it works this way as does using the open() function to create
# a file object directly.
tempfd = os.open(tempfn,
os.O_EXCL | os.O_CREAT | os.O_TRUNC | os.O_RDWR)
tempobj = os.fdopen(tempfd, 'wb')
tempobj.write('hello, world')
tempobj.close()
os.remove(tempfn)
time.sleep(10)
def main():
for count in range(NUM_THREADS):
if count % 100 == 0:
print('Opening thread %s' % count)
wthread = threading.Thread(target=worker_tempfile)
#wthread = threading.Thread(target=worker_notempfile, args=(count,))
started = False
while not started:
try:
wthread.start()
started = True
except thread.error:
print('failed starting thread %s; sleeping' % count)
time.sleep(3)
if __name__ == '__main__':
main()
Se l'eseguo con la worker_notempfile
linea attiva e la linea di worker_tempfile
commentato-out, si corre a compimento.
Il contrario (utilizzando worker_tempfile
) ottengo il seguente errore:
$ python threadtempfiletest.py
Opening thread 0
Opening thread 100
Opening thread 200
Opening thread 300
Exception in thread Thread-301:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/threading.py", line 460, in __bootstrap
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/threading.py", line 440, in run
File "threadtempfiletest.py", line 17, in worker_tempfile
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/tempfile.py", line 302, in mkstemp
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/tempfile.py", line 236, in _mkstemp_inner
OSError: [Errno 24] Too many open files: '/var/folders/4L/4LtD6bCvEoipksvnAcJ2Ok+++Tk/-Tmp-/tmpJ6wjV0'
Tutte le idee che sto facendo male? Questo è un bug in Python, o sono ossessionato?
UPDATE 2009-12-14: credo di aver trovato la risposta, ma non mi piace. Dal momento che nessuno è stato in grado di replicare il problema, sono andato a caccia nel nostro ufficio per le macchine. Ha trasmesso tutto tranne la mia macchina. Ho provato su un Mac con le stesse versioni del software che stavo usando. Sono persino andato a cercare un Desktop G5 con la stessa configurazione hardware e software che avevo - lo stesso risultato. Entrambi i test (con tempfile e senza tempfile) sono riusciti su tutto.
Per kick ho scaricato Python 2.6.4 e l'ho provato sul mio desktop e lo stesso pattern sul mio sistema come Python 2.5.1: tempfile non riuscito e notempfile riuscito.
Questo mi sta portando alla conclusione che qualcosa è nascosto sul mio Mac, ma di certo non riesco a capire cosa. Qualsiasi suggerimento è benvenuto.
Impossibile aiutare, ma +1 per una domanda chiara con un buon codice. –
Puoi darci la versione di Python, per favore? Non so se è importante, ma potrebbe. –
Jonathan: Grazie mille! Peter: Python 2.5.1. Ho anche modificato la domanda per riflettere questo. – Schof