Splice (системный вызов) - Splice (system call)

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

Работы

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

Линус Торвальдс описанный сращивание () в электронном письме 2006 г., которое было включено в KernelTrap статья.[1]

Происхождение

В Linux реализация splice заимствует некоторые идеи из оригинального предложения Ларри Маквой в 1998 г.[2] Системные вызовы splice впервые появились в Linux версия ядра 2.6.17 и были написаны Йенс Аксбо.

Прототип

 ssize_t сращивание(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, беззнаковый int флаги);

Некоторые константы, которые представляют интерес:

/ * Флажки сращивания (еще не выложены в камне). * /#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

Пример

Это пример сращивания в действии:

/ * Перенос с диска в журнал. * /int log_blocks (структура log_handle * ручка, int fd, loff_t компенсировать, size_t размер){    int Filedes [2];    int Ret;    size_t написать = размер;    Ret = трубка (Filedes);    если (Ret < 0)        идти к из;    / * вставляем файл в канал (данные в памяти ядра). * /    пока (написать > 0) {        Ret = сращивание (fd, &компенсировать, Filedes [1], НОЛЬ, написать,                SPLICE_F_MORE | SPLICE_F_MOVE);        если (Ret < 0)            идти к трубка;        еще            написать -= Ret;    }    написать = размер;    / * вставляем данные из конвейера (в памяти ядра) в файл. * /    пока (написать > 0) {        Ret = сращивание (Filedes [0], НОЛЬ, ручка->fd,                &(ручка->fd_offset), написать,                SPLICE_F_MORE | SPLICE_F_MOVE);        если (Ret < 0)            идти к трубка;        еще            написать -= Ret;    }трубка:    Закрыть (Filedes [0]);    Закрыть (Filedes [1]);из:    если (Ret < 0)        возвращаться -errno;    возвращаться 0;}

Дополнительные системные вызовы

сращивание () является одним из трех системных вызовов, завершающих сращивание () архитектура. vmsplice () может отображать область данных приложения в канал (или наоборот), что позволяет передавать данные между каналами и пользовательской памятью, где sys_splice () передача между файловым дескриптором и конвейером. тройник () это последняя часть трилогии. Он дублирует один канал на другой, позволяя создавать вилки так, как приложения соединяются с трубами.

Требования

Когда используешь сращивание () с сокетами сетевой контроллер (NIC) должен поддерживать DMA, иначе splice () не приведет к значительному повышению производительности. Причина этого в том, что каждая страница канала просто заполняется до размера кадра (1460 байт из доступных 4096 байт на страницу).

Не все типы файловых систем поддерживают сращивание (). Также, AF_UNIX сокеты не поддерживают сращивание ().

Смотрите также

Рекомендации

  1. ^ «Linux: объяснение splice () и tee ()». kerneltrap.org. 2006-04-21. Архивировано из оригинал на 2013-05-21. Получено 2014-04-27.
  2. ^ «Архивная копия». Архивировано из оригинал на 2016-03-04. Получено 2016-02-28.CS1 maint: заархивированная копия как заголовок (связь)

внешняя ссылка