/ / Czy python zipfile wątku bezpieczne? - python, django, thread-safety, seler, zipfile

Czy python zipfile jest wątkowo bezpieczny? - python, django, thread-safety, seler, zipfile

W projekcie django muszę wygenerować pliki pdf dla obiektów w db. Ponieważ generowanie każdego pliku trwa kilka sekund, używam selera do uruchamiania zadań asynchronicznie.

Problem polega na tym, że muszę dodać każdy plik do zipaarchiwum. Planowałem użyć modułu python zipfile, ale różne zadania mogą być uruchamiane w różnych wątkach i zastanawiam się, co się stanie, jeśli dwa zadania będą próbowały dodać plik do archiwum w tym samym czasie.

Czy poniższy kod jest bezpieczny, czy nie? Nie mogę znaleźć żadnych cennych informacji w oficjalnym dokumencie Pythona.

try:
zippath = os.path.join(pdf_directory, "archive.zip")
zipfile = ZipFile(zippath, "a")
zipfile.write(pdf_fullname)
finally:
zipfile.close()

Uwaga: działa w Pythonie 2.6

Odpowiedzi:

4 dla odpowiedzi № 1

Nie, w tym sensie nie jest to wątek bezpieczny. Jeśli dodajesz do tego samego pliku zip, potrzebujesz tam blokady lub zawartość pliku może zostać pomieszana. Jeśli dołączasz do różnych plików zip, użyj osobnego ZipFile() obiekty, to wszystko jest w porządku.


0 dla odpowiedzi nr 2

Podczas gdy to pytanie jest stare, nadal jest wysoko na wynikach Google, więc chcę tylko powiedzieć, że zauważyłem na pythona 3.4 64bit w oknach plik zipfile lzma jest wątkowo bezpieczny, wszystkie inne zawodzą.

with zipfile.ZipFile("test.zip", "w", zipfile.ZIP_LZMA) as zip:
#do stuff in threads

Zauważ, że nie możesz powiązać tego samego pliku z wieloma instancjami zipfile.ZipFile, zamiast tego musisz użyć tego samego we wszystkich wątkach, tutaj jest to zmienna o nazwie zip.

W moim przypadku uzyskuję około 80-90% wykorzystania procesora na 8 rdzeniach i SSD, co jest miłe.


0 dla odpowiedzi № 3

Python 3.5.5 zapisuje do ZipFile i czyta wiele wątków ZipExtFiles: https://docs.python.org/3.5/whatsnew/changelog.html#id93

O ile mogę powiedzieć, zmiana nie została przeniesiona do Pythona 2.7.

Aktualizacja: po przestudiowaniu kodu i kilku testach okazuje się, że blokowanie nie zostało jeszcze w pełni wdrożone. Działa poprawnie tylko dla writestr i nie pracuje dla open i write.