Какой объем данных выбирает (2) гарантирует возможность записи в файл без блокировки - PullRequest
2 голосов
/ 03 июня 2011

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

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

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

Ответы [ 4 ]

3 голосов
/ 03 июня 2011

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

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

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

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

3 голосов
/ 03 июня 2011

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

3 голосов
/ 03 июня 2011

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

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

1 голос
/ 03 июня 2011

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

...