>  기사  >  시스템 튜토리얼  >  Linux에서의 메모리 매핑 mmap: 원리, 사용법 및 장점

Linux에서의 메모리 매핑 mmap: 원리, 사용법 및 장점

王林
王林앞으로
2024-02-10 10:00:23784검색

메모리 매핑 mmap은 Linux 시스템의 중요한 메모리 관리 메커니즘으로, 이를 통해 사용자 공간 프로세스는 시스템 호출이나 데이터 복사 없이 물리적 메모리나 파일에 직접 액세스할 수 있습니다. 이를 통해 메모리 활용도와 액세스 효율성이 향상되어 시스템 리소스와 시간이 절약됩니다. 하지만 mmap이 어떻게 작동하는지 정말로 이해하고 있나요? Linux에서 mmap을 사용하는 방법을 알고 있습니까? mmap의 장점과 한계를 알고 계십니까? 이 기사에서는 Linux에서 메모리 매핑 mmap에 대한 관련 지식을 자세히 소개하므로 Linux에서 이 강력한 메모리 관리 도구를 더 잘 사용하고 이해할 수 있습니다.

2. 기본 기능

mmap 함수는 unix/linux에서의 시스템 호출입니다. 자세한 내용은 "Unix Netword 프로그래밍" 2권 12.2절을 참조하세요.

mmap 시스템 호출은 공유 메모리와 함께 사용하도록 완전히 설계되지 않았습니다. 그 자체로 일반 파일에 대한 다른 액세스 방법을 제공합니다. 프로세스는 메모리 읽기 및 쓰기와 같은 일반 파일에서 작동할 수 있습니다. Posix 또는 System V의 공유 메모리 IPC는 순전히 공유 목적으로 사용됩니다. 물론 공유 메모리의 mmap() 구현도 주요 응용 프로그램 중 하나입니다.

으아악 으아악

mmap은 파일을 메모리 공간에 매핑하는 데 사용됩니다. 간단히 말해서 mmap은 메모리에 파일 내용의 이미지를 만드는 것입니다. 매핑이 성공한 후 이 메모리 영역에 대한 사용자의 수정 사항은 커널 공간에 직접 반영될 수 있습니다. 마찬가지로 이 영역에 대한 커널 공간의 수정 사항도 사용자 공간에 직접 반영됩니다. 그러면 커널 공간과 사용자 공간 간에 대량의 데이터 전송이 필요한 작업에 매우 효율적입니다.

원칙

먼저 "매핑"이라는 단어는 수학 시간에 언급된 "일대일 매핑"과 같은 의미를 가지고 있는데, 여기서는 주로 위치를 말합니다. 그림 1의 프로세스 1에 표시된 것처럼 하드 디스크의 파일과 프로세스 논리 주소 공간이 동일한 크기의 영역 간 일대일 대응입니다. 이 대응은 순전히 논리적 개념이며 물리적으로 존재하지 않습니다. 그 이유는 프로세스 자체의 논리적 주소 공간이 존재하지 않기 때문입니다. 메모리 매핑 과정에서는 실제 데이터 복사가 이루어지지 않으며, 해당 파일은 메모리에 논리적으로 저장되며, 해당 코드에 따라 관련 데이터 구조(struct address_space)가 설정되고 초기화됩니다. process 구현할 시스템 호출 mmap()이 있으므로 메모리 매핑 설정 효율성이 매우 높습니다.

Linux 下的内存映射 mmap:原理、用法和优势

그림 1. 메모리 매핑 원리

실제 데이터 복사 없이 메모리 매핑이 이루어지는데, 프로세스가 메모리 연산을 통해 최종적으로 어떻게 하드 디스크의 파일에 직접 접근할 수 있을까요? 이는 메모리 매핑 이후의 여러 관련 프로세스에 따라 달라집니다.

mmap()은 프로세스의 논리 주소 공간에 있는 주소를 가리키는 포인터 ptr을 반환합니다. 이러한 방식으로 프로세스는 파일을 읽고 쓰기 위해 더 이상 읽기 또는 쓰기를 호출할 필요가 없으며 ptr만 사용하면 됩니다. 파일을 조작하십시오. 그러나 ptr은 논리 주소를 가리키며, 그 안에 있는 데이터를 연산하기 위해서는 그림 1의 2번 과정과 같이 논리 주소를 MMU를 통해 물리 주소로 변환해야 한다. 이 프로세스는 메모리 매핑과 아무 관련이 없습니다.

앞서 언급했듯이 메모리 매핑을 설정한다고 해서 실제로 데이터가 복사되는 것은 아닙니다. 이때 MMU는 주소 매핑 테이블에서 ptr에 해당하는 물리적 주소를 찾을 수 없습니다. 즉, MMU가 실패하고 페이지 오류 인터럽트가 발생합니다. 페이지 폴트 인터럽트 인터럽트 응답 기능은 스왑에서 해당 페이지를 검색합니다. 찾을 수 없는 경우(즉, 파일을 메모리로 읽은 적이 없는 경우) 매핑 관계를 통해 하드 디스크에서 파일을 읽습니다. 그림 1의 프로세스 3에 표시된 것처럼 mmap()에 의해 설정됩니다. 이 프로세스는 메모리 매핑과 아무 관련이 없습니다.

데이터 복사 시 물리적 메모리가 부족한 것으로 확인되면 그림 1의 4번 과정과 같이 가상 메모리 메커니즘(스왑)을 통해 일시적으로 사용되지 않은 물리적 페이지를 하드 디스크로 스왑합니다. 이 프로세스는 메모리 매핑과도 관련이 없습니다.

效率

从代码层面上看,从硬盘上将文件读入内存,都要经过文件系统进行数据拷贝,并且数据拷贝操作是由文件系统和硬件驱动实现的,理论上来说,拷贝数据的效率是一样的。但是通过内存映射的方法访问硬盘上的文件,效率要比read和write系统调用高,这是为什么呢?原因是read()是系统调用,其中进行了数据拷贝,它首先将文件内容从硬盘拷贝到内核空间的一个缓冲区,如图2中过程1,然后再将这些数据拷贝到用户空间,如图2中过程2,在这个过程中,实际上完成了 两次数据拷贝 ;而mmap()也是系统调用,如前所述,mmap()中没有进行数据拷贝,真正的数据拷贝是在缺页中断处理时进行的,由于mmap()将文件直接映射到用户空间,所以中断处理函数根据这个映射关系,直接将文件从硬盘拷贝到用户空间,只进行了 一次数据拷贝 。因此,内存映射的效率要比read/write效率高。

Linux 下的内存映射 mmap:原理、用法和优势

图2.read系统调用原理

下面这个程序,通过read和mmap两种方法分别对硬盘上一个名为“mmap_test”的文件进行操作,文件中存有10000个整数,程序两次使用不同的方法将它们读出,加1,再写回硬盘。通过对比可以看出,read消耗的时间将近是mmap的两到三倍。

  1 #include
  2 
  3 #include
  4 
  5 #include
  6 
  7 #include
  8 
  9 #include
 10 
 11 #include
 12 
 13 #include
 14 
 15 #include
 16 
 17 #include
 18 
 19  
 20 
 21 #define MAX 10000
 22 
 23  
 24 
 25 int main()
 26 
 27 {
 28 
 29 int i=0;
 30 
 31 int count=0, fd=0;
 32 
 33 struct timeval tv1, tv2;
 34 
 35 int *array = (int *)malloc( sizeof(int)*MAX );
 36 
 37  
 38 
 39 /*read*/
 40 
 41  
 42 
 43 gettimeofday( &tv1, NULL );
 44 
 45 fd = open( "mmap_test", O_RDWR );
 46 
 47 if( sizeof(int)*MAX != read( fd, (void *)array, sizeof(int)*MAX ) )
 48 
 49 {
 50 
 51 printf( "Reading data failed.../n" );
 52 
 53 return -1;
 54 
 55 }
 56 
 57 for( i=0; iif( sizeof(int)*MAX != write( fd, (void *)array, sizeof(int)*MAX ) )
 64 
 65 {
 66 
 67 printf( "Writing data failed.../n" );
 68 
 69 return -1;
 70 
 71 }
 72 
 73 free( array );
 74 
 75 close( fd );
 76 
 77 gettimeofday( &tv2, NULL );
 78 
 79 printf( "Time of read/write: %dms/n", tv2.tv_usec-tv1.tv_usec );
 80 
 81  
 82 
 83 /*mmap*/
 84 
 85  
 86 
 87 gettimeofday( &tv1, NULL );
 88 
 89 fd = open( "mmap_test", O_RDWR );
 90 
 91 array = mmap( NULL, sizeof(int)*MAX, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0 );
 92 
 93 for( i=0; iprintf( "Time of mmap: %dms/n", tv2.tv_usec-tv1.tv_usec );
110 
111  
112 
113 return 0;
114 
115 }

通过本文,你应该对 Linux 下的内存映射 mmap 有了一个深入的了解,知道了它的定义、原理、用法和优势。你也应该明白了 mmap 的适用场景和注意事项,以及如何在 Linux 下正确地使用 mmap。我们建议你在需要高效地访问物理内存或者文件时,使用 mmap 来提高程序的性能和可移植性。同时,我们也提醒你在使用 mmap 时要注意一些潜在的风险和问题,如同步、保护、错误处理等。希望本文能够帮助你更好地使用 Linux 系统,让你在 Linux 下享受内存映射的便利和快感。

위 내용은 Linux에서의 메모리 매핑 mmap: 원리, 사용법 및 장점의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 lxlinux.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제