Какой объем данных select (2) гарантирует возможность записи в файл без блокировки

select (2) (среди прочего) говорит мне, могу ли я писать в fd файла без блокировки. Однако гарантирует ли это мне, что я могу записать полные 4096 байт без блокировки?

Примечание Меня интересуют обычные файлы на диске. Не розетки и тому подобное.

Другими словами: сигнализирует ли select, когда мы можем просто записать один единственный байт в файл fd без блокировки, или сигнализирует ли он, когда мы можем записать n (4096, .. .?) байт в файл fd без блокировки.


person bas    schedule 03.06.2011    source источник


Ответы (4)


Всякий раз, когда select() указывает, что ваш файл готов, вы можете попробовать записать N байтов для любого N>0. write() вернет количество фактически записанных байтов. Если он равен N, вы можете написать снова. Если меньше N, то следующая запись будет заблокирована.

Примечание Обычные файлы на диске не блокируются. Розетки, трубы и клеммы.

person n. 1.8e9-where's-my-share m.    schedule 03.06.2011

Вы пометили это «Linux», так что же говорит вам исходный код ядра? Должно быть довольно легко прочитать реализацию системного вызова, чтобы определить, когда select решает рассматривать файловый дескриптор как готовый к записи.

Однако, если вы беспокоитесь о блокировке, вы делаете это неправильно. Если вы не хотите блокировать, используйте O_NONBLOCK или эквиваленты. Даже если бы select действительно гарантировал, что определенное количество байтов может быть записано без блокировки, это было бы верно только во время возврата select; это не обязательно может быть правдой к тому времени, когда вы фактически выполняете запись.

person Jeremy W. Sherman    schedule 03.06.2011

Примечание. Меня интересуют обычные файлы на диске. Не розетки и тому подобное.

select не "работает" с обычными файлами, только с sockets/pipes/ttys и, возможно, с другими, но не с обычными файлами. Для обычных файлов select всегда будет сигнализировать о том, что дескриптор файла доступен для чтения/записи, поэтому использовать select с файлами довольно бесполезно.

обратите внимание, что это относится и к другим средствам мультиплексирования ввода-вывода, таким как poll/epoll. AIO будет выполнять асинхронный ввод-вывод с обычными файлами, но поддержка операционной системы может варьироваться, и это довольно сложный API для использования

Что касается того, сколько данных вы можете записать, обещаний нет. 4096 не является волшебным числом, которое select предполагает, что вы можете писать без блокировки, когда применяется к дескрипторам файлов, где использование select имеет смысл (сокеты/каналы/и т. д.). Поскольку вы не можете знать, сколько данных вы можете записать без блокировки, вы всегда должны устанавливать файловый дескриптор на неблокирующий, записывать, сколько фактически было записано, как указано возвращаемым значением записи/отправки, и начинать запись с этой точки. В следующий раз select указывает, что вы можете снова записывать данные.

person nos    schedule 03.06.2011

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

person ribram    schedule 03.06.2011