Hiện tại, tôi đang cố gắng hiểu giá trị của mối nối/vmsplice. Về trường hợp sử dụng của IPC, tôi stumbled khi câu trả lời sau đây trên stackoverflow: https://stackoverflow.com/a/1350550/1305501Linux Zero-Copy: Chuyển các trang bộ nhớ giữa hai quy trình với vmsplice
Câu hỏi: Làm thế nào để chuyển các trang bộ nhớ từ một quá trình quá trình khác sử dụng vmsplice mà không sao chép dữ liệu (ví dụ: zero-copy)?
Câu trả lời được đề cập ở trên cho rằng điều đó là có thể. Tuy nhiên, nó không chứa bất kỳ mã nguồn nào. Nếu tôi hiểu tài liệu của vmsplice
chính xác, chức năng sau sẽ chuyển các trang bộ nhớ vào một đường ống (bộ đệm hạt nhân) mà không cần sao chép, nếu bộ nhớ được cấp phát và căn chỉnh đúng cách. Lỗi xử lý bị bỏ qua để dễ dàng trình bày.
// 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);
}
}
Nhưng làm cách nào để các trang bộ nhớ được truy cập từ không gian người dùng mà không cần sao chép? Rõ ràng các phương pháp sau đây không hoạt động:
vmsplice
: Chức năng này cũng có thể được sử dụng theo hướng ngược lại. Nhưng theo nhận xét trong số kernel sources, dữ liệu sẽ được sao chép.read
: Tôi có thể tưởng tượng, rằng chức năng này thực hiện một số phép thuật nếu bộ nhớ được căn chỉnh đúng cách, nhưng tôi nghi ngờ điều đó.mmap
: Không thể trên đường ống. Nhưng có một số loại tệp ảo có thể được sử dụng thay thế, tức làsplice
các trang bộ nhớ cho tệp ảo vàmmap
không?- ...?
Hoàn toàn không thể với vmsplice
?
Tôi không nghĩ rằng nên tạo một hàm không tĩnh có tên là "send()". – wildplasser
Thật vậy, đó là gọi hành vi không xác định trên POSIX. –
Tôi không nghĩ rằng lệnh gọi 'vmsplice' của bạn trong' receive' có ý nghĩa. Đó là một cuộc gọi để viết, không phải để đọc ... –