Université de Bouïra – Département d'Informatique
Année universitaire 2016-2017
Module : Systèmes d'exploitation (23ème année SITPN)
Programme C utilisant un segment mémoire partagé entre un processus père et deux processus fils
#include <sys/shm.h>#include <sys/wait.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#define CLEF 12346 // Définition d'une clé arbitraireint main(void) {int i, j;int *mem = NULL;int shmid; /* Identificateur du segment de mémoire partagée */int flag; /* Drapeau attaché au segment */key_t mykey;int pid[3];mykey = ftok(".", 'a');if((shmid = shmget(mykey, sizeof(*mem), 0666 | IPC_CREAT)) < 0) {/* Création d'un nouveau segment mémoire de taille "taille de la structure data" octets,avec droits d'écriture et de lecture */perror("shmget"); // Vérification de la création de l'espace mémoireexit(1);}printf("L'identificateur du segment est %d\n", shmid);for(i = 0; i < 2; i++) {switch(pid[i] = fork()) {case -1:perror("Impossible de créer un fils");return -1;case 0:printf("Salut, je suis le fils numéro %d (PID = %d)\n", i, getpid());printf("Fils : Je commence par m'attacher au segment de mémoire\n");mem = shmat(shmid, 0, flag);printf("***** Fils mem = %d\n", *mem);if(mem == (int *) -1) {perror("Attachement impossible");exit(1);}printf("Je vais écrire un message que le père affichera\n");for(j = 0; j < 10000; j++) {if(i == 0) {*mem -= 1;} else {*mem += 1;}}printf("Fils mem = %d, i = %d, j = %d\n", *mem, i, getpid());if(shmdt(mem) == -1) {perror("Detachement impossible");exit(1);}exit(0);default:printf("Je suis le père\n");}}printf("Père : Je commence par m'attacher au segment de mémoire\n");mem = shmat(shmid, 0, flag);if(mem == (int *) -1) {perror("Attachement impossible");exit(1);}printf("Le père attend la mort de ses fils\n");for(i = 0; i < 2; i++) {wait(0);}printf("Je vais afficher un message que mes fils ont écrit\n");printf("%d\n", *mem);*mem = 0;printf("Avant tout, détachons les segments partagés\n");if(shmdt(mem) == -1) {perror("Detachement impossible");exit(1);}printf("Les fils ont terminé\n");return 1;}Questions fréquentes (FAQ)
1. Que fait ce programme ?
Ce programme C crée un segment de mémoire partagée accessible par un processus père et deux processus fils. Il initialise une variable entière dans ce segment, puis les fils modifient cette valeur (l'un l'incrémente, l'autre la décrémente) pendant 10 000 itérations. Le père attend la fin des fils avant d'afficher le résultat final.
2. Pourquoi utiliser un segment mémoire partagé ?
Les segments mémoire partagés permettent une communication rapide et efficace entre processus liés (père et fils). Ils évitent les échanges coûteux via des fichiers ou des tubes (pipes) et sont souvent utilisés pour synchroniser des données entre processus.
3. Que se passe-t-il si le segment n'est pas correctement détaché ?
Si le segment mémoire partagé n'est pas détaché avec shmdt(), le système conserve une référence sur celui-ci, ce qui peut entraîner des fuites de mémoire ou des comportements inattendus lors de la suppression du segment avec shmctl().