Возможна ли асинхронная запись файла в Python?

Есть ли простой способ асинхронной записи в файл в Python?

Я знаю, что файл io, который поставляется с Python блокирует; что нормально в большинстве случаев. В этом конкретном случае мне нужны записи, чтобы вообще не блокировать приложение или, по крайней мере, как можно меньше.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
21
0
22 371
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Twisted имеет неблокирующая запись в файловые дескрипторы. Если вы пишете асинхронный код, я все равно ожидаю, что вы будете использовать twisted. :)

К сожалению, O_NONBLOCK (что действительно делает API fdesc, на который вы ссылаетесь) не работает с файлами локального жесткого диска. то есть в спецификации POSIX сказано, что его следует игнорировать, и он покорно игнорируется во всех известных мне UNIX-системах. Если вы думаете, что это глупая идея, я не могу согласиться с этим, но есть много исторических причин и причин реализации, почему это так. Короче говоря, если вам нужен асинхронный ввод-вывод для файлов локального жесткого диска, вам лучше использовать потоки и отложить ввод-вывод для потока ввода-вывода или использовать AIO API.

mathieu 17.02.2012 17:50

Насколько я понимаю, асинхронный ввод-вывод - это не совсем то же самое, что неблокирующий ввод-вывод.

В случае неблокирующего ввода-вывода, как только дескриптор файла настроен на «неблокирующий», системный вызов read() (например) вернет EWOULDBLOCK (или EAGAIN), если операция чтения заблокирует вызывающий процесс в чтобы завершить операцию. Системные вызовы select(), poll(), epoll() и т. д. Предусмотрены для того, чтобы процесс мог запрашивать уведомление ОС, когда один или несколько файловых дескрипторов становятся доступный для выполнения некоторой операции ввода-вывода.

Асинхронный ввод-вывод работает путем постановки в очередь запроса ввода-вывода к файловому дескриптору, отслеживаемого независимо от вызывающего процесса. Для файлового дескриптора, который поддерживает асинхронный ввод-вывод (как правило, необработанные дисковые устройства), процесс может вызвать aio_read() (например), чтобы запросить чтение некоторого количества байтов из файлового дескриптора. Системный вызов возвращается немедленно, независимо от того, завершился ввод-вывод. Некоторое время спустя процесс затем опрашивает операционную систему на предмет завершение ввода-вывода (то есть буфер заполняется данными).

Процесс (однопоточный), который выполняет только неблокирующий ввод-вывод, сможет читать или писать из одного файлового дескриптора, готового для ввода-вывода, когда другой не готов. Но процесс должен по-прежнему синхронно выполнять системные вызовы для выполнения ввода-вывода для всех готовых файловых дескрипторов. В то время как в случае асинхронного ввода-вывода процесс просто проверяет завершение ввода-вывода (буфер заполнен данными). При асинхронном вводе-выводе ОС может работать параллельно в максимально возможной степени для обслуживания ввода-вывода, если она того пожелает.

При этом есть ли какие-нибудь оболочки для системных вызовов POSIX aio_read / write и т. д. Для Python?

Следует добавить: как говорит комментатор в первом ответе, на самом деле никакие системы не следуют O_NONBLOCK для файлов - это действительно только для сокетов. Если вам нужен переносимый ввод-вывод асинхронных файлов в Unix, вы должны использовать POSIX AIO или выгружать синхронный ввод-вывод в пул потоков.

Conrad Meyer 10.03.2012 04:46

Python 3, похоже, обладает такой функциональностью. См. PEP 3116.

Похоже, что PEP 3116 связан с новой абстракцией ввода-вывода, которая включает неблокирующий ввод-вывод. Однако неблокирующий ввод-вывод - это не то же самое, что асинхронный ввод-вывод. Неблокирующий ввод-вывод обычно не применяется к записи в локальную файловую систему.

Robie Basak 28.12.2010 12:18

Я разрабатываю ставки aio.h для python: пьяо

Работает только на Linux ..

Вы можете попробовать использовать Thread:

from threading import Thread

for file in list_file:
     tr = Thread(target=file.write, args=(data,))
     tr.start()

Это более или менее псевдокод, но я надеюсь, что вы уловили идею. Имейте в виду, что темы здесь остаются открытыми.

По моему опыту, это сработало хорошо, хотя интерпретатор продолжает работать некоторое время, пока основной скрипт завершен (необходимо использовать join()), поэтому прирост скорости настолько велик, чем кажется.

Другие вопросы по теме