Unix 계열 시스템에서 메모리 매핑(mmap() 시스템 호출을 통해 구현됨)의 개념을 이해할 수 있는 방식으로 설명할 수 있는 사람이 있습니까? 이 기능은 언제 필요합니까?
답변1
고려 사항: 두 프로세스가 동시에 읽고 쓰기 위해 동일한 파일을 열 수 있으므로 둘 사이에 일종의 통신이 있을 수 있습니다.
프로세스 A가 파일에 쓸 때 먼저 자체 프로세스별 메모리 내의 버퍼를 일부 데이터로 채운 다음 write
이 함수를 호출하여 해당 버퍼를 커널이 소유한 다른 버퍼에 복사합니다(실제로 이는 페이지 캐시 항목이 됩니다). 커널이 더티로 표시되고 결국 디스크에 다시 기록됩니다.
이제 프로세스 B는 동일한 파일의 동일한 지점에서 읽습니다. read
데이터는 페이지 캐시의 동일한 위치에서 B 메모리의 버퍼로 복사됩니다.
두 개의 복사본이 필요합니다. 먼저 데이터가 A에서 "공유" 메모리로 복사된 다음 다시 "공유" 메모리에서 B로 복사됩니다.
mmap
A를 사용하면 페이지 캐시를 자체 주소 공간에서 직접 사용할 수 있습니다 . 이제 중간 버퍼를 채우는 대신 데이터를 동일한 "공유" 메모리로 직접 포맷하고 복사를 피할 수 있습니다.
마찬가지로 B는 mmap
페이지를 직접그것은주소 공간. 이제 A가 "공유" 메모리에 넣는 모든 것을 별도의 버퍼에 복사하지 않고 직접 액세스할 수 있습니다.
(분명히 이 시나리오를 IPC에 사용하려면 일종의 동기화가 필요하지만 이는 범위를 벗어납니다.)
이제 A가 파일이 저장된 장치의 드라이버로 대체되는 경우를 고려하십시오. ,B를 사용하여 mmap
파일에 액세스합니다 .아직중복 복사본(DMA 또는 기타입력하다페이지 캐싱은 불가피하지만 복제는 필요하지 않습니다.다시B의 버퍼에 넣습니다).
물론 몇 가지 단점이 있습니다. 예를 들어:
장치 및 OS가 비동기 파일 I/O를 지원하는 경우 이를 사용하여 읽기/쓰기 차단을 피할 수 있습니다. 그러나 매핑된 페이지를 읽거나 쓰면 직접 처리할 수 없는 차단 페이지 오류가 발생할 수 있습니다. 그것을 피하기 위해 등을 사용
mincore
)파일의 끝을 읽으려는 시도를 막지 않거나 좋은 방법으로 파일에 추가하는 데 도움이 됩니다(길이를 확인하거나 명시적으로
truncate
파일을 늘려야 함).