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