Il existe deux approches: shmget
et mmap
. Je vais en parler mmap
, car c'est plus moderne et flexible, mais vous pouvez jeter un coup d'œil à man shmget
( ou à ce tutoriel ) si vous préférez utiliser les outils à l'ancienne.
La mmap()
fonction peut être utilisée pour allouer des tampons de mémoire avec des paramètres hautement personnalisables pour contrôler l'accès et les autorisations, et pour les sauvegarder avec le stockage du système de fichiers si nécessaire.
La fonction suivante crée un tampon en mémoire qu'un processus peut partager avec ses enfants:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
void* create_shared_memory(size_t size) {
// Our memory buffer will be readable and writable:
int protection = PROT_READ | PROT_WRITE;
// The buffer will be shared (meaning other processes can access it), but
// anonymous (meaning third-party processes cannot obtain an address for it),
// so only this process and its children will be able to use it:
int visibility = MAP_SHARED | MAP_ANONYMOUS;
// The remaining parameters to `mmap()` are not important for this use case,
// but the manpage for `mmap` explains their purpose.
return mmap(NULL, size, protection, visibility, -1, 0);
}
Voici un exemple de programme qui utilise la fonction définie ci-dessus pour allouer un tampon. Le processus parent écrira un message, un fork, puis attendra que son enfant modifie le tampon. Les deux processus peuvent lire et écrire la mémoire partagée.
#include <string.h>
#include <unistd.h>
int main() {
char parent_message[] = "hello"; // parent process will write this message
char child_message[] = "goodbye"; // child process will then write this one
void* shmem = create_shared_memory(128);
memcpy(shmem, parent_message, sizeof(parent_message));
int pid = fork();
if (pid == 0) {
printf("Child read: %s\n", shmem);
memcpy(shmem, child_message, sizeof(child_message));
printf("Child wrote: %s\n", shmem);
} else {
printf("Parent read: %s\n", shmem);
sleep(1);
printf("After 1s, parent read: %s\n", shmem);
}
}
shmget()
et al. et aussi l'mmap()
approche pure avecMAP_ANON
(akaMAP_ANONYMOUS
) - bien qu'elleMAP_ANON
ne soit pas définie par POSIX. Il existe également POSIXshm_open()
etshm_close()
pour la gestion des objets de mémoire partagée. […shm_unlink()
), alors que les mécanismes utilisantmmap()
nécessitent un fichier etMAP_SHARED
persistent les données (etMAP_ANON
empêche la persistance). Il y a un exemple complet dans la section Justification de la spécification deshm_open()
.