Является ли запись в сокет произвольным ограничением системного вызова sendfile()?

StackOverflow https://stackoverflow.com/questions/1876993

Вопрос

Прелюдия

sendfile() — чрезвычайно полезный системный вызов по двум причинам:

Во-первых, это меньше кода чем read()/write() (или recv()/send() если вы предпочитаете этот джайв).
Во-вторых, это Быстрее (меньше системных вызовов, реализация может копировать между устройствами без буфер и т. д.), чем вышеупомянутые методы.

Меньше кода.Более эффективным.Потрясающий.

В UNIX все (в основном) представляет собой файл.Это уродливая территория столкновения платонической теории и реальной практики.Я понимаю, что сокеты принципиально отличаются от файлов, находящихся на каком-либо устройстве.Я не копался в исходниках Linux/*BSD/Darwin/любой операционной системы. sendfile() чтобы узнать, почему этот конкретный системный вызов ограничен записью в сокеты (в частности, потоковые сокеты).

Я просто хочу знать...

Вопрос

Что ограничивает sendfile() от того, чтобы дескриптор целевого файла был чем-то помимо сокета (например, дисковым файлом или каналом)?

Это было полезно?

Решение

По сути, единственное, что его ограничивает, это то, что «никто еще не написал код».

Однако я понимаю, что причина того, что никто не написал код для этих двух случаев, которые вы упомянули, заключается в том, что они оба потребуют копирования данных, что лишает большую часть преимуществ использования sendfile в первую очередь.

  • Для файла в файл sendfile, вам понадобится копия, потому что в противном случае одна и та же страница должна была бы находиться в кэше страниц как чистая страница в исходном файле и как грязная страница в целевом файле.Я не думаю, что кэш страниц на данный момент создан для обработки этого случая (хотя, конечно, это можно было бы изменить, если бы была достаточная мотивация).

  • Для файла в канал sendfile, вам все равно нужна копия, потому что процесс назначения должен получить частную, доступную для записи копию данных.В любом случае, для большинства случаев использования этого случая у нас уже есть mmap.

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

Кажется, я помню, что это ограничение было введено в ранней версии Linux 2.6 (в 2.4 этого ограничения не было).

Начиная с версии 2.6.17 в Linux имеется аналогичный системный вызов splice();более гибкий, но немного менее эффективный.Линус говорил о повторной реализации sendfile с точки зрения splice().Видеть http://kerneltrap.org/node/6505

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top