Mam interesujący problem z wątkami i modułem tempfile w Pythonie. Coś wygląda na to, że nie zostanie oczyszczone, dopóki wątki nie znikną, a ja działam na otwartym limicie plików. (To jest na OS X 10.5.8, Python 2.5.1.)Python tempfile moduł i wątki nie grają ładnie; Co ja robię źle?
Ale jeśli w pewnym sensie replikuję to, co robi moduł tempfile (nie wszystkie kontrole bezpieczeństwa, ale po prostu generowanie deskryptora pliku, a następnie używanie os. fdopen do utworzenia obiektu pliku) Nie mam żadnych problemów.
Zanim złożyłem to jako błąd w Pythonie, pomyślałem, że sprawdzę tutaj, ponieważ jest bardziej prawdopodobne, że robię coś subtelnie nie tak. Ale jeśli tak, to dzień, w którym próbowałem to rozgryźć, nigdzie mnie nie dostał.
#!/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()
Jeśli uruchomić go z worker_notempfile
linia aktywnym i worker_tempfile
linii zakomentowanych, biegnie do końca.
Innym sposobem wokół (używając worker_tempfile
) pojawia się następujący błąd:
$ 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'
jakieś pomysły, co robię źle? Czy jest to błąd w Pythonie, czy też jestem zuchwały?
AKTUALIZACJA 2009-12-14: Myślę, że znalazłem odpowiedź, ale nie podoba mi się to. Ponieważ nikt nie był w stanie powtórzyć problemu, zacząłem polować w naszym biurze na maszyny. Przekazał wszystko poza moją maszyną. Testowałem na komputerze Mac z tymi samymi wersjami oprogramowania, których używałem. Poszedłem nawet na polowanie na komputer stacjonarny G5 z konfiguracją tego samego sprzętu i oprogramowania, którą miałem - taki sam wynik. Oba testy (z tempfile i bez tempfile) zakończyły się pomyślnie.
W przypadku kopnięć pobrałem wersję Python 2.6.4 i wypróbowałem ją na moim komputerze, i ten sam wzorzec w moim systemie, ponieważ Python 2.5.1: tempfile nie powiodło się, a notempfile powiodło się.
Prowadzi mnie to do wniosku, że coś dzieje się na moim Macu, ale na pewno nie wiem, co. Wszelkie sugestie są mile widziane.
Nie można pomóc, ale +1 dla jasnego pytania z dobrym kodem. –
Czy możesz podać wersję Pythona? Nie wiem, czy to ma znaczenie, ale może. –
Jonathan: Wielkie dzięki! Peter: Python 2.5.1. Zmieniłem też to pytanie, aby to odzwierciedlić. – Schof