сращивание (системный вызов)
Эта статья нуждается в дополнительных цитатах для проверки . ( март 2011 г. ) |
splice() — это Linux , специфичный для системный вызов , который перемещает данные между файловым дескриптором и каналом без обращения в пространство пользователя. Соответствующий системный вызов vmsplice() перемещает или копирует данные между каналом и пользовательским пространством. В идеале splice и vmsplice работают путем переназначения страниц и фактически не копируют какие-либо данные, что может повысить производительность ввода-вывода . Поскольку линейные адреса не обязательно соответствуют смежным физическим адресам, это может быть невозможно во всех случаях и во всех комбинациях оборудования.
Работает
[ редактировать ]С splice() можно перемещать данные из одного файлового дескриптора в другой, не создавая никаких копий из пользовательского пространства в пространство ядра, что обычно требуется для обеспечения безопасности системы, а также для сохранения простого интерфейса для процессов чтения и записи файлов. splice() работает с использованием буфера канала . Конвейерный буфер — это буфер памяти в ядре, который непрозрачен для процесса пользовательского пространства. Пользовательский процесс может вставить содержимое исходного файла в этот буфер канала, а затем вставить буфер канала в файл назначения, и все это без перемещения каких-либо данных через пространство пользователя.
Происхождение
[ редактировать ]Линус Торвальдс описал splice() в электронном письме 2006 года, которое было включено в статью KernelTrap . [1]
Реализация сращивания Linux заимствует некоторые идеи из оригинального предложения Ларри Маквоя в 1998 году. [2] Системные вызовы сращивания впервые появились в Linux версии 2.6.17. ядре [1] и были написаны Йенсом Аксбо .
Прототип
[ редактировать ] ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);
Некоторые константы, которые представляют интерес:
/* Splice flags (not laid down in stone yet). */
#ifndef SPLICE_F_MOVE
#define SPLICE_F_MOVE 0x01
#endif
#ifndef SPLICE_F_NONBLOCK
#define SPLICE_F_NONBLOCK 0x02
#endif
#ifndef SPLICE_F_MORE
#define SPLICE_F_MORE 0x04
#endif
#ifndef SPLICE_F_GIFT
#define SPLICE_F_GIFT 0x08
#endif
Пример
[ редактировать ]Это пример сращивания в действии:
/* Transfer from disk to a log. */
int log_blocks (struct log_handle * handle, int fd, loff_t offset, size_t size)
{
int filedes [2];
int ret;
size_t to_write = size;
ret = pipe (filedes);
if (ret < 0)
goto out;
/* splice the file into the pipe (data in kernel memory). */
while (to_write > 0) {
ret = splice (fd, &offset, filedes [1], NULL, to_write,
SPLICE_F_MORE | SPLICE_F_MOVE);
if (ret < 0)
goto pipe;
else
to_write -= ret;
}
to_write = size;
/* splice the data in the pipe (in kernel memory) into the file. */
while (to_write > 0) {
ret = splice (filedes [0], NULL, handle->fd,
&(handle->fd_offset), to_write,
SPLICE_F_MORE | SPLICE_F_MOVE);
if (ret < 0)
goto pipe;
else
to_write -= ret;
}
pipe:
close (filedes [0]);
close (filedes [1]);
out:
if (ret < 0)
return -errno;
return 0;
}
Дополнительные системные вызовы
[ редактировать ]splice() — один из трех системных вызовов, завершающих Архитектура splice() . vmsplice() может отображать область данных приложения в канал (или наоборот), тем самым обеспечивая передачу между каналами и пользовательской памятью, где sys_splice() осуществляет передачу между файловым дескриптором и каналом. tee() — последняя часть трилогии. Он дублирует один канал в другой, позволяя разветвлять способ подключения приложений к каналам.
Требования
[ редактировать ]При использовании splice() с сокетами сетевой контроллер (NIC) должен поддерживать DMA, в противном случае splice() не обеспечит значительного повышения производительности. Причина этого в том, что каждая страница канала просто заполняется до размера кадра (1460 байт из доступных 4096 байт на страницу). splice() не поддерживает сокеты UDP.
Не все типы файловых систем поддерживают сращивание() . Также, Сокеты AF_UNIX не поддерживают сращивание() .
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ Jump up to: а б «Linux: объяснение splice() и tee()» . kerneltrap.org. 21 апреля 2006 г. Архивировано из оригинала 21 мая 2013 г. Проверено 27 апреля 2014 г.
- ^ «Архивная копия» . Архивировано из оригинала 4 марта 2016 г. Проверено 28 февраля 2016 г.
{{cite web}}
: CS1 maint: архивная копия в заголовке ( ссылка )
Внешние ссылки
[ редактировать ]- Ядро Linux 2.6.17 (kernelnewbies.org)
- Два новых системных вызова: splice() и sync_file_range() ( LWN.net ).
- Некоторые новые системные вызовы (LWN.net)