Несколько потоков Python, обращающихся к одному и тому же файлу - PullRequest
12 голосов
/ 20 февраля 2010

У меня есть два потока, один, который пишет в файл, а другой, который периодически перемещает файл в другое место. Операторы записи всегда вызывают open до написания сообщения и close после написания сообщения. Движитель использует shutil.move для перемещения.

Я вижу, что после того, как первый ход сделан, писатель больше не может записывать в файл, то есть размер файла всегда равен 0 после первого хода. Я что-то не так делаю?

Ответы [ 3 ]

26 голосов
/ 20 февраля 2010

Блокировка - это возможное решение, но я предпочитаю общую архитектуру, в которой каждый внешний ресурс (включая файл) обрабатывается одним отдельным потоком. Другие потоки отправляют рабочие запросы выделенному потоку в экземпляре Queue.Queue (и предоставляют отдельную собственную очередь в качестве части параметров рабочего запроса, если им нужно вернуть результат), выделенный поток тратит большую часть его время ожидания на .get в этой очереди и всякий раз, когда он получает запросы, продолжается и выполняет его (и возвращает результаты в переданной очереди, если необходимо).

Я привел подробные примеры этого подхода, например, в "Питоне в двух словах". Очередь Python по своей сути поточно-ориентирована и значительно упрощает вашу жизнь.

Одним из преимуществ этой архитектуры является то, что она плавно переводится в многопроцессорность , если и когда вы решите переключить некоторую работу на отдельный процесс вместо отдельного потока (например, чтобы использовать преимущества нескольких ядер) - - multiprocessing предоставляет собственный рабочий тип Queue, чтобы сделать такой переход гладким, как шелк; -).

7 голосов
/ 20 февраля 2010

Когда два потока обращаются к одним и тем же ресурсам, происходят странные вещи. Чтобы избежать этого, всегда блокируйте ресурс. В Python есть удобный threading.Lock для этого, а также некоторые другие инструменты (см. Документацию модуля threading).

4 голосов
/ 20 февраля 2010

Выезд http://www.evanfosmark.com/2009/01/cross-platform-file-locking-support-in-python/

Вы можете использовать простую блокировку с его кодом, как написал Эван Фосмарк в старом вопросе StackOverflow:

from filelock import FileLock

with FileLock("myfile.txt"):
    # work with the file as it is now locked
    print("Lock acquired.")

Одна из самых элегантных библиотек, которые я когда-либо видел.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...