2012-05-17 5 views
18

현재 splice/vmsplice의 값을 이해하려고합니다. IPC의 사용 사례에 대해서는, I에 유래에 다음과 같은 답변을 우연히 : https://stackoverflow.com/a/1350550/1305501Linux Zero-Copy : vmsplice를 사용하여 두 프로세스간에 메모리 페이지를 전송하십시오.

질문 : 어떻게 데이터 (즉, 제로 - 카피)를 복사하지 않고 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 :이 기능은 반대 방향을 위해 또한 이용 될 수있다. 그러나 kernel sources에있는 의견에 따르면 데이터가 복사됩니다.
  • read :이 함수는 메모리가 제대로 정렬되어 있으면 약간의 마술을하지만 상상할 수 있습니다.
  • mmap : 파이프에서는 불가능합니다. 그러나 가상 파일 대신에 splice 가상 파일에 메모리 페이지가 있고 mmap이라면 사용할 수있는 가상 파일이 있습니까?
  • ...?

vmsplice과 전혀 호환되지 않습니까?

+4

"send()"라는 비 정적 함수를 만드는 것이 좋습니다. – wildplasser

+1

사실 그것은 POSIX에서 정의되지 않은 동작을 호출합니다. –

+0

''수신 '에서'vmsplice'에 대한 호출이 의미가 있다고 생각하지 않습니다. 글을 쓰는 것이지, 읽지는 말은 아니다. –

답변

6

마찬가지로 .. 언급 한대로 fd를 수신 프로세스 somehow으로 전달하고 다른 쪽에서는 fd로 사용하면됩니다.

편집 : 는 사실, 당신은 파이프의 다른 쪽 끝에있는 수신 측의 배관 및 스플 라이스()에 버퍼를 매핑하는 송신 측에() vmsplice를 사용해야합니다. 예 : here을 참조하십시오.

또 다른 선택은 공유 mmaping을 사용하는 것입니다.

+3

다른 프로세스가 이미 파이프의 다른 쪽 끝에 fd를 가지고 있다고 가정합니다. 질문 : 데이터를 복사하지 않고 메모리 페이지를 주소 공간에 매핑 할 수 있습니까? 나는'read (2)'에 그러한 최적화가 포함되어 있는지 의심 스럽다. – nosid

+0

커널이이 페이지 매핑을 처리해야합니다. 또한, 내 편집을 참조하십시오. – dtatulea