проверка, когда все данные отправляются с использованием неблокирующего открытия - PullRequest
0 голосов
/ 04 октября 2010

Если я открою файл как os.open( '/dev/ttyS2', O_RDWR | O_NDELAY ), могу ли я проверить, когда мои команды write () завершены? Или я могу открыть файл для неблокирующего чтения, но для блокирующей записи?

Ответы [ 6 ]

3 голосов
/ 05 октября 2010

Вы неправильно понимаете, что означает неблокирование. Это не подразумевает асинхронную операцию - вы можете иметь любую комбинацию асинхронного / синхронного и блокирующего / неблокирующего.

A write() просто передает данные ядру, чтобы позаботиться о них. Когда write() успешно возвращается, ядро ​​теперь позаботилось о данных - это верно независимо от того, является ли файловый дескриптор блокирующим или неблокирующим. Независимо от того, завершило ли ядро ​​запись этого вопроса, это отдельный вопрос (обычно ответ «нет» - большинство файловых дескрипторов асинхронные).

A write() не может завершиться, если у ядра больше нет места для буферизации данных, которые вы хотите записать, и на этот случай влияет неблокирование по сравнению с блокировкой - в случае блокировки write() заблокировать, пока не освободится место. В неблокирующем случае write() вернет ошибку (EAGAIN), и вы можете повторить попытку позже.

Если вы хотите подождать, пока все данные, записанные на оконечное устройство, будут фактически отправлены на аппаратное обеспечение, используйте tcdrain() - но это, вероятно, не нужно. В качестве альтернативы, если вы хотите, чтобы write() блокировался до тех пор, пока ваши данные не будут приняты ядром, вы можете использовать fcntl(), чтобы временно установить дескриптор файла на блокировку.

3 голосов
/ 05 октября 2010

Если вы пишете в tty (как в вашем примере), вы можете использовать termios.tcdrain для ожидания передачи всех записанных байтов.

Ваши write системные вызовы все равно будутнеблокируемый, поэтому вам нужно будет обрабатывать EWOULDBLOCK / EAGAIN ошибок и использовать select(2), poll(2) или epoll(7), чтобы узнать, когда вы можете записать в дескриптор файла.Они предназначены для использования с неблокирующими файловыми дескрипторами.

1 голос
/ 04 октября 2010

Флаг O_NDELAY всегда влияет как на чтение, так и на запись. Для достижения блокирующей записи в неблокирующем файле вы можете выбрать (модуль Python) файл и выполнить запись, когда он станет доступным для записи в цикле.

0 голосов
/ 04 октября 2010

Вы пробовали os.fsync(fd)?

0 голосов
/ 04 октября 2010

Откройте два файловых дескриптора в одном месте - один для неблокирующих операций чтения, а другой для блокировки записей.

0 голосов
/ 04 октября 2010

OS API write () возвращает количество записанных байтов.Сравнивая это значение с размером вашего ввода, вы можете увидеть, когда все входные данные отправлены.

...