Какво количество данни гарантира 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", така че какво ви казва изходният код на ядрото? Трябва да е доста лесно да се прочете изпълнението на syscall, за да се установи кога select реши да третира файлов дескриптор като готов за писане.

Ако обаче се притеснявате от блокирането, го правите погрешно. Ако не искате да блокирате, използвайте O_NONBLOCK или еквиваленти. Дори ако select гарантира, че определен брой байтове могат да бъдат записани без блокиране, това би било вярно само в момента, в който select се връща; може да не е непременно вярно до момента, в който действително извършите записа.

person Jeremy W. Sherman    schedule 03.06.2011

Забележете, че се интересувам от нормални файлове на диск. Не гнезда или други подобни.

select не "работи" с нормални файлове, само sockets/pipes/ttys и евентуално други, но не и обикновени файлове. За обикновени файлове select винаги ще сигнализира файловия дескриптор като годен за четене/запис - следователно е доста безполезно упражнение да се използва select с файлове.

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

Колко данни можете да запишете, няма обещание. 4096 не е магическо число, което select предполага, че можете да пишете без блокиране, когато се прилага към файлови дескриптори, където използването на select има смисъл (сокети/тръби/и т.н.). Тъй като не можете да знаете колко данни можете да запишете без блокиране, винаги трябва да задавате файловия дескриптор на неблокиращ, да записвате колко действително е записано, както е посочено от върнатата стойност на запис/изпращане и да започнете да пишете от тази точка next time select показва, че можете да записвате данни отново.

person nos    schedule 03.06.2011

select() само обещава, че приложимото повикване може да бъде направено без блокиране, не гарантира I/O количество (4096) във вашия случай. Тъй като select() може да се използва с различни типове дескриптори (файл, сокети, серийни връзки и т.н.), може да забележите, че за дисковите операции наблюдаваното поведение е, че винаги може да се запише пълен буфер, но отново това е специфично за конкретна основна операция, а не обещание за select().

person ribram    schedule 03.06.2011