Python WindowsLinuxmacOSPython 3

Python: После параллельного выполнения Python теряет изменения файла

  • Обновлено
  • Чтение ≈ 3 минуты

Краткий ответ

При одновременной записи несколькими процессами или потоками изменения файла могут теряться: каждый писатель читает старую версию, перезаписывает чужую запись либо конфликтует с другим процессом.

В этой статье
  1. Что произошло и когда проявляется ошибка
  2. Причины и диагностические признаки
  3. Подробная пошаговая диагностика и исправление
  4. Как проверить, что проблема устранена
  5. Если исправление не помогло

#Что произошло и когда проявляется ошибка

При одновременной записи несколькими процессами или потоками изменения файла могут теряться: каждый писатель читает старую версию, перезаписывает чужую запись либо конфликтует с другим процессом.

#Причины и диагностические признаки

Возможная причинаКак узнатьЧто делать
Запись с режимом w в нескольких процессахopen(...,"w") обнуляет файл перед записью.В файле остаётся результат только последнего заданияРазделить выходные файлы и объединять после завершения.
Чтение-изменение-запись без синхронизацииНесколько исполнителей меняют одну копию состояния.Иногда пропадают инкременты и строкиСделать единственного писателя или транзакционное хранилище.
Параллельная запись в один файлЗаписи процессов не согласованы на уровне приложения.Строки перемешаны или поврежденыИспользовать очередь результатов и один поток записи.

#Подробная пошаговая диагностика и исправление

  1. 1. Сделайте резервную копию и воспроизведите на тестовом файлеСкопируйте исходный результат в отдельную папку. Определите, одновременно ли работают процессы, потоки или задачи планировщика; проверьте, не открывается ли один и тот же файл с режимом w или x. Не запускайте повторную проверку на боевой базе или файле с пользовательскими данными.
  1. 2. Найдите общий участок чтения и записиВ коде поищите read_text() → изменение строки → write_text(), а также несколько open(...,"a") из разных исполнителей. Даже если отдельный вызов записи кажется коротким, последовательность чтение–изменение–запись не становится автоматически безопасной.
  1. 3. Разделите выходы независимых задачДля пакетной обработки проще всего писать отдельный файл на каждую задачу, а после завершения объединять результаты строго в одном процессе. Пример демонстрирует уникальные имена по номеру задачи, не удаляя уже существующие файлы.
  2. Пример кода по теме
    Python
    Номер задачи в реальном параллельном запуске должен быть уникальным; x запрещает перезапись.
    from pathlib import Path
    folder = Path("results")
    folder.mkdir(exist_ok=True)
    for job_id in range(3):
        with (folder / f"job-{job_id}.txt").open("x", encoding="utf-8") as f:
            f.write(f"job={job_id}\n")
  1. 4. Для потоков синхронизируйте общую операциюЕсли запись производится из потоков одного процесса, создайте общий threading.Lock и охватите блокировкой весь участок изменения состояния; блокировка не синхронизирует отдельные процессы. Для нескольких процессов лучше очередь с одним писателем или SQLite с транзакциями и обработкой конфликтов.
  2. Только для потоков одного процесса и общего объекта lock
    Python
    Только для потоков одного процесса и общего объекта lock.
    import threading
    lock = threading.Lock()
    def append_result(line):
        with lock:
            with open("result.txt", "a", encoding="utf-8") as f:
                f.write(line + "\n")
  1. 5. Проверьте подсчёт и целостность после параллельного тестаНа небольшой копии запустите фиксированное число заданий, сравните количество уникальных записей, отсутствие повторов и предсказуемый итог. Применяя SQLite, используйте транзакцию, а не ручное переписывание общего JSON. Не считайте проверку успешной по одному случайному запуску.

#Как проверить, что проблема устранена

На серии воспроизводимых параллельных запусков число результатов совпадает с числом задач, нет потерянных или частично записанных строк.

#Если исправление не помогло

Для межпроцессной синхронизации не подставляйте threading.Lock: он действует только внутри процесса. На сетевых папках гарантии блокировок и атомарных операций могут различаться.

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.