Maison  >  Article  >  Tutoriel système  >  Mappage mémoire mmap sous Linux : principes, utilisation et avantages

Mappage mémoire mmap sous Linux : principes, utilisation et avantages

王林
王林avant
2024-02-10 10:00:23712parcourir

Le mappage de la mémoire mmap est un mécanisme de gestion de la mémoire important dans les systèmes Linux. Il permet aux processus de l'espace utilisateur d'accéder directement à la mémoire physique ou aux fichiers sans effectuer d'appels système ni copier de données. Cela peut améliorer l'utilisation de la mémoire et l'efficacité de l'accès, économisant ainsi des ressources système et du temps. Mais comprenez-vous vraiment comment fonctionne mmap ? Savez-vous comment utiliser mmap sous Linux ? Connaissez-vous les avantages et les limites de mmap ? Cet article vous présentera en détail les connaissances pertinentes sur le mappage de mémoire mmap sous Linux, afin que vous puissiez mieux utiliser et comprendre ce puissant outil de gestion de mémoire sous Linux.

2. Fonctions de base

La fonction mmap est un appel système sous unix/linux Pour plus de détails, veuillez vous référer à la section 12.2 du volume 2 de "Programmation Unix Netword".

L'appel système mmap n'est pas entièrement conçu pour être utilisé avec la mémoire partagée. Il fournit lui-même une méthode d'accès différente aux fichiers ordinaires. Le processus peut fonctionner sur des fichiers ordinaires comme la lecture et l'écriture de la mémoire. La mémoire partagée IPC de Posix ou System V est uniquement utilisée à des fins de partage. Bien entendu, l'implémentation mmap() de la mémoire partagée est également l'une de ses principales applications.

<code style="display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px"> **mmap系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。mmap并不分配空间, 只是将文件映射到调用进程的地址空间里(但是会占掉你的 virutal memory), 然后你就可以用memcpy等操作写文件, 而不用write()了.写完后,内存中的内容并不会立即更新到文件中,而是有一段时间的延迟,你可以调用msync()来显式同步一下, 这样你所写的内容就能立即保存到文件里了.这点应该和驱动相关。 不过通过mmap来写文件这种方式没办法增加文件的长度, 因为要映射的长度在调用mmap()的时候就决定了.如果想取消内存映射,可以调用munmap()来取消内存映射**
</code>
void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset)

mmap est utilisé pour mapper des fichiers dans l'espace mémoire. En termes simples, mmap consiste à créer une image du contenu d'un fichier en mémoire. Une fois le mappage réussi, les modifications apportées par l'utilisateur à cette zone mémoire peuvent être directement reflétées dans l'espace noyau. De même, les modifications apportées par l'espace noyau à cette zone sont également directement reflétées dans l'espace utilisateur. L'efficacité est donc très élevée pour les opérations qui nécessitent une grande quantité de transmission de données entre l'espace noyau et l'espace utilisateur.

Principe

Tout d'abord, le mot « cartographie » a la même signification que la « cartographie biunivoque » évoquée en cours de mathématiques, qui consiste à établir une correspondance biunivoque. Ici, il fait principalement référence à l'emplacement de. le fichier sur le disque dur et l'espace d'adressage logique du processus. Correspondance biunivoque entre des zones de même taille, comme indiqué dans le processus 1 de la figure 1. Cette correspondance est un concept purement logique et n'existe pas physiquement. La raison en est que l'espace d'adressage logique du processus lui-même n'existe pas. Dans le processus de mappage de la mémoire, il n'y a pas de copie réelle des données. Le fichier n'est pas chargé dans la mémoire, mais est logiquement placé dans la mémoire. Spécifique au code, la structure de données correspondante (struct adresse_espace) est établie et initialisée. processus Il y a un appel système mmap() à implémenter, donc l'efficacité de l'établissement du mappage mémoire est très élevée.

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

Figure 1. Principe de cartographie mémoire

Puisque le mappage mémoire est établi sans copie réelle des données, comment le processus peut-il enfin accéder directement aux fichiers sur le disque dur via des opérations de mémoire ? Cela dépend de plusieurs processus liés après le mappage de la mémoire.

mmap() renverra un pointeur ptr, qui pointe vers une adresse dans l'espace d'adressage logique du processus. De cette façon, le processus n'a plus besoin d'appeler read ou write pour lire et écrire le fichier, mais n'a besoin que d'utiliser ptr pour. exploiter le fichier. Cependant, ptr pointe vers une adresse logique. Pour exploiter les données qu'elle contient, l'adresse logique doit être convertie en adresse physique via la MMU, comme indiqué dans le processus 2 de la figure 1. Ce processus n'a rien à voir avec le mappage de la mémoire.

Comme mentionné précédemment, l'établissement du mappage de mémoire ne copie pas réellement les données. À ce stade, la MMU ne peut pas trouver l'adresse physique correspondant à ptr dans la table de mappage d'adresses. Autrement dit, la MMU échoue et génère une interruption de défaut de page. Interruption de défaut de page La fonction de réponse à l'interruption recherchera la page correspondante dans le swap. Si elle ne peut pas être trouvée (c'est-à-dire que le fichier n'a jamais été lu dans la mémoire), le fichier sera lu à partir du disque dur via la relation de mappage. établi par mmap(). Mettez-le dans la mémoire physique, comme indiqué dans le processus 3 de la figure 1. Ce processus n'a rien à voir avec le mappage de la mémoire.

S'il s'avère que la mémoire physique n'est pas suffisante lors de la copie des données, les pages physiques temporairement inutilisées seront échangées sur le disque dur via le mécanisme de mémoire virtuelle (swap), comme indiqué dans le processus 4 de la figure 1. Ce processus n'a également rien à voir avec le mappage de la mémoire.

效率

从代码层面上看,从硬盘上将文件读入内存,都要经过文件系统进行数据拷贝,并且数据拷贝操作是由文件系统和硬件驱动实现的,理论上来说,拷贝数据的效率是一样的。但是通过内存映射的方法访问硬盘上的文件,效率要比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 下享受内存映射的便利和快感。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer