Подтвердить что ты не робот

Linux Zero-Copy: Перенос страниц памяти между двумя процессами с помощью vmsplice

В настоящее время я пытаюсь понять значение splice/vmsplice. Что касается варианта использования IPC, я наткнулся на следующий ответ на stackoverflow: qaru.site/info/288121/...

Вопрос: Как переносить страницы памяти из одного процесса в другой процесс с использованием vmsplice без копирования данных (т.е. нулевой копии)?

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

// data is aligned to page boundaries,
// and length is a multiple of the page size
void transfer_to_pipe(int pipe_out, char* data, size_t length)
{
    size_t offset = 0;
    while (offset < length) {
        struct iovec iov { data + offset, length - offset };
        offset += vmsplice(pipe_out, &iov, 1, SPLICE_F_GIFT);
    }
}

Но как можно получить доступ к страницам памяти из пользовательского пространства без копирования? По-видимому, следующие методы не работают:

  • vmsplice: Эта функция также может использоваться для обратного направления. Но в соответствии с комментариями в источниках ядра данные будут скопированы.
  • read: Я могу представить, что эта функция делает магию, если память правильно выровнена, но я сомневаюсь.
  • mmap: невозможно на трубе. Но есть ли какой-то виртуальный файл, который можно использовать вместо него, т.е. splice страницы памяти для виртуального файла и mmap it?
  • ...?

Не возможно ли вообще с vmsplice?

4b9b3361

Ответ 1

Как упоминалось в R.., вам нужно только передать fd в процесс получения как-то, а с другой стороны использовать его как обычный fd.

изменить: Фактически, вы должны использовать vmsplice() на стороне отправки, чтобы сопоставить буфер с трубой и сращиванием() на принимающей стороне на другом конце трубы. Пример здесь.

Другим выбором будет использование общего mmap-ing.