Introduction aux IPC POSIX

Ce forum est dédié à apprendre le développement de programmes user mode sur Linux

Moderator: Rick

Post Reply
Hydraxx
Site Admin
Posts: 114
Joined: Mon Jan 12, 2026 4:04 pm
Location: France
Contact:

Introduction aux IPC POSIX

Post by Hydraxx »

Introduction aux IPC POSIX

1. Introduction

POSIX fournit plusieurs mécanismes permettant à des processus de communiquer ou de se synchroniser entre eux.

Ces mécanismes sont appelés IPC, pour Inter-Process Communication.

Les IPC POSIX ont été introduits comme une alternative aux mécanismes IPC System V.

Les trois principaux mécanismes IPC POSIX sont :
  • Les files de messages POSIX.
  • Les sémaphores POSIX.
  • La mémoire partagée POSIX.
Ils remplissent globalement les mêmes rôles que leurs équivalents System V, mais leur interface est différente et généralement plus homogène.


2. Les trois mécanismes IPC POSIX

2.1 Les files de messages POSIX

Les files de messages permettent à plusieurs processus d'échanger des messages.

Contrairement à un pipe, les données ne forment pas obligatoirement un simple flux continu d'octets.

Chaque message possède sa propre frontière.

Par exemple, si un processus envoie deux messages :

Code: Select all

"START"
puis :

Code: Select all

"STOP"
le processus récepteur peut récupérer séparément les deux messages.

Les principales fonctions sont :

Code: Select all

mq_open()
mq_close()
mq_unlink()
mq_send()
mq_receive()
Il existe également des fonctions permettant de gérer les attributs de la file ou les notifications :

Code: Select all

mq_getattr()
mq_setattr()
mq_notify()

Priorité des messages

Une particularité importante des files de messages POSIX est la possibilité d'attribuer une priorité à chaque message.

Un message de priorité élevée peut être récupéré avant un message de priorité plus faible.

Cela permet donc de gérer facilement des messages urgents.


3. Les sémaphores POSIX

3.1 Principe

Les sémaphores servent principalement à synchroniser plusieurs threads ou plusieurs processus.

Un sémaphore POSIX contient une valeur entière qui ne peut pas devenir négative.

Deux opérations fondamentales sont utilisées :

Code: Select all

sem_wait()
sem_post()

sem_wait()

sem_wait() tente de décrémenter la valeur du sémaphore.

Si la valeur est supérieure à 0, elle est décrémentée immédiatement.

Si la valeur vaut 0, le thread ou le processus appelant est bloqué jusqu'à ce qu'une ressource devienne disponible.


sem_post()

sem_post() incrémente la valeur du sémaphore.

Cette opération peut réveiller un thread ou un processus bloqué dans sem_wait().


Exemple conceptuel

Sémaphore initialisé à :

Code: Select all

1
Processus A :

Code: Select all

sem_wait()
Valeur :

Code: Select all

1 -> 0
A entre dans la section critique.

Processus B appelle ensuite :

Code: Select all

sem_wait()
Mais la valeur vaut déjà 0.

B est donc bloqué.

Lorsque A termine :

Code: Select all

sem_post()
Valeur :

Code: Select all

0 -> 1
B peut alors continuer.


4. Sémaphores nommés et non nommés

POSIX fournit deux catégories de sémaphores.

Sémaphores nommés

Ils possèdent un nom et peuvent être utilisés facilement entre plusieurs processus indépendants.

Ils sont créés ou ouverts avec :

Code: Select all

sem_open()
Ils sont fermés avec :

Code: Select all

sem_close()
Leur nom est supprimé avec :

Code: Select all

sem_unlink()

Sémaphores non nommés

Ils sont directement stockés dans une zone mémoire.

Ils utilisent notamment :

Code: Select all

sem_init()
sem_destroy()
Lorsqu'un sémaphore non nommé doit être partagé entre plusieurs processus, il doit se trouver dans une zone mémoire réellement partagée entre ces processus.


5. Mémoire partagée POSIX

5.1 Principe

La mémoire partagée permet à plusieurs processus d'accéder à une même zone mémoire.

C'est généralement l'un des mécanismes IPC les plus rapides.

Au lieu d'envoyer les données à travers le noyau à chaque échange, plusieurs processus peuvent mapper le même objet mémoire dans leur espace d'adressage virtuel.


Création de l'objet

La fonction principale est :

Code: Select all

shm_open()
Elle permet de créer ou d'ouvrir un objet de mémoire partagée POSIX.

Exemple :

Code: Select all

int fd = shm_open("/shared_mem", O_CREAT | O_RDWR, 0666);
shm_open() retourne un descripteur de fichier.


Dimension de l'objet

Après la création, l'objet possède généralement une taille qui doit être définie.

On utilise pour cela :

Code: Select all

ftruncate()
Exemple :

Code: Select all

ftruncate(fd, 4096);

Mapping

La mémoire peut ensuite être mappée dans l'espace virtuel du processus avec :

Code: Select all

mmap()
Exemple :

Code: Select all

void *ptr = mmap(
    NULL,
    4096,
    PROT_READ | PROT_WRITE,
    MAP_SHARED,
    fd,
    0
);

MAP_SHARED

MAP_SHARED signifie que les modifications réalisées dans la zone mappée sont visibles par les autres processus ayant mappé le même objet.


6. Nommage des objets IPC POSIX

Les objets IPC POSIX nommés utilisent généralement un nom commençant par :

Code: Select all

/
Exemples :

Code: Select all

"/myqueue"
"/mysem"
"/shared_mem"
Ces noms ne correspondent pas nécessairement à de véritables fichiers visibles comme des fichiers classiques.

Le noyau utilise ce nom pour identifier l'objet IPC.


Exemples

File de messages :

Code: Select all

mq_open("/queue", ...);
Sémaphore :

Code: Select all

sem_open("/sem", ...);
Mémoire partagée :

Code: Select all

shm_open("/memory", ...);

7. Création et ouverture d'un objet IPC

Les interfaces POSIX utilisent souvent une logique ressemblant à open().

Par exemple :

Code: Select all

mq_open()
sem_open()
shm_open()
On retrouve donc certains flags classiques des fichiers Unix.


O_CREAT

O_CREAT demande de créer l'objet s'il n'existe pas déjà.

Exemple :

Code: Select all

shm_open("/memory", O_CREAT | O_RDWR, 0666);

O_EXCL

O_EXCL est généralement utilisé avec O_CREAT.

Si l'objet existe déjà, l'opération échoue.

Exemple :

Code: Select all

shm_open(
    "/memory",
    O_CREAT | O_EXCL | O_RDWR,
    0666
);
Cela permet de s'assurer que le processus crée réellement un nouvel objet.


8. Permissions

Lors de la création d'un objet IPC POSIX, on peut souvent fournir des permissions similaires aux permissions des fichiers Unix.

Exemple :

Code: Select all

0666
Cela correspond à :
  • lecture + écriture pour le propriétaire ;
  • lecture + écriture pour le groupe ;
  • lecture + écriture pour les autres.
Ces permissions restent cependant affectées par le umask du processus.


9. Descripteurs et handles

Les mécanismes POSIX n'utilisent pas tous exactement le même type de handle.

La mémoire partagée retourne un descripteur de fichier classique :

Code: Select all

int fd;
Exemple :

Code: Select all

int fd = shm_open(...);
Les files de messages utilisent :

Code: Select all

mqd_t
Exemple :

Code: Select all

mqd_t queue = mq_open(...);
Les sémaphores nommés utilisent un pointeur :

Code: Select all

sem_t *
Exemple :

Code: Select all

sem_t *sem = sem_open(...);

10. Suppression d'un objet IPC

Fermer un objet et supprimer son nom sont deux opérations différentes.

C'est un principe important des IPC POSIX.


File de messages

Fermer :

Code: Select all

mq_close()
Supprimer le nom :

Code: Select all

mq_unlink()

Sémaphore nommé

Fermer :

Code: Select all

sem_close()
Supprimer le nom :

Code: Select all

sem_unlink()

Mémoire partagée

Fermer le descripteur :

Code: Select all

close()
Supprimer le nom :

Code: Select all

shm_unlink()

11. Principe de unlink

unlink ne signifie pas nécessairement que l'objet disparaît immédiatement.

Il supprime son nom.

Les processus qui possèdent déjà une référence valide vers l'objet peuvent généralement continuer à l'utiliser.

L'objet sera réellement détruit lorsque les références restantes auront disparu.

Ce comportement ressemble au fonctionnement de unlink() avec les fichiers Unix.


12. Comparaison avec System V IPC

System V possède lui aussi :
  • des files de messages ;
  • des sémaphores ;
  • de la mémoire partagée.
Mais l'interface est différente.


System V

On rencontre notamment :

Code: Select all

msgget()
msgsnd()
msgrcv()

semget()
semop()
semctl()

shmget()
shmat()
shmdt()
shmctl()
Les objets System V sont souvent identifiés avec des identifiants numériques retournés par le noyau.

Ils peuvent également utiliser des clés de type :

Code: Select all

key_t

POSIX

On utilise plutôt :

Code: Select all

mq_open()
mq_send()
mq_receive()

sem_open()
sem_wait()
sem_post()

shm_open()
mmap()
Les objets nommés POSIX utilisent généralement des noms sous forme de chaînes de caractères.


13. Différence importante concernant les sémaphores

Les sémaphores System V peuvent être organisés en ensembles de plusieurs sémaphores.

Une opération semop() peut également effectuer des opérations plus complexes sur ces ensembles.

Avec POSIX, un objet sem_t représente directement un sémaphore individuel.

Cela rend souvent l'utilisation plus simple.


System V

Code: Select all

semget()
semop()
semget() peut créer un ensemble contenant plusieurs sémaphores.

semop() permet de réaliser des opérations sur ces sémaphores.


POSIX

Chaque sem_t représente essentiellement un sémaphore.

Les opérations principales sont :

Code: Select all

sem_wait()
sem_post()

14. Différence concernant les files de messages

Avec System V, les messages possèdent généralement un champ :

Code: Select all

long mtype;
Ce type peut être utilisé par msgrcv() pour sélectionner certains messages.


Exemple System V

Code: Select all

struct message {
    long mtype;
    char data[128];
};
Avec POSIX, le mécanisme est différent.

Chaque message peut recevoir une priorité.

Exemple :

Code: Select all

mq_send(queue, buffer, size, priority);
Le noyau peut ainsi placer les messages de priorité élevée avant les messages de priorité plus faible.


15. Différence concernant la mémoire partagée

Avec System V :

Code: Select all

shmget()
crée ou récupère un segment.

Puis :

Code: Select all

shmat()
attache le segment à l'espace virtuel du processus.


Avec POSIX

Code: Select all

shm_open()
retourne un descripteur.

Puis :

Code: Select all

mmap()
mappe la mémoire partagée.

Cette approche s'intègre donc directement au mécanisme général de mapping mémoire Unix.


16. Exemple minimal de mémoire partagée POSIX

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>

int main(void)
{
    int fd = shm_open(
        "/demo",
        O_CREAT | O_RDWR,
        0666
    );

    if (fd == -1) {
        perror("shm_open");
        return EXIT_FAILURE;
    }

    if (ftruncate(fd, 4096) == -1) {
        perror("ftruncate");
        close(fd);
        return EXIT_FAILURE;
    }

    char *ptr = mmap(
        NULL,
        4096,
        PROT_READ | PROT_WRITE,
        MAP_SHARED,
        fd,
        0
    );

    if (ptr == MAP_FAILED) {
        perror("mmap");
        close(fd);
        return EXIT_FAILURE;
    }

    strcpy(ptr, "Inside The System");

    munmap(ptr, 4096);
    close(fd);

    shm_unlink("/demo");

    return EXIT_SUCCESS;
}

17. Étapes générales d'utilisation

Le fonctionnement général d'un objet IPC POSIX nommé ressemble souvent à ceci :
  • Donner un nom à l'objet.
  • Créer ou ouvrir l'objet.
  • Configurer l'objet si nécessaire.
  • Utiliser l'objet pour communiquer ou se synchroniser.
  • Fermer la référence locale.
  • Supprimer le nom de l'objet lorsqu'il n'est plus nécessaire.

Exemple mémoire partagée

Code: Select all

shm_open()
    ↓
ftruncate()
    ↓
mmap()
    ↓
lecture / écriture
    ↓
munmap()
    ↓
close()
    ↓
shm_unlink()

Exemple file de messages

Code: Select all

mq_open()
    ↓
mq_send() / mq_receive()
    ↓
mq_close()
    ↓
mq_unlink()

Exemple sémaphore nommé

Code: Select all

sem_open()
    ↓
sem_wait() / sem_post()
    ↓
sem_close()
    ↓
sem_unlink()

18. Avantages des IPC POSIX

Les IPC POSIX possèdent plusieurs avantages :
  • API généralement plus homogène.
  • Utilisation de noms lisibles pour les objets nommés.
  • Intégration naturelle avec certaines API Unix classiques.
  • shm_open() fonctionne avec mmap().
  • Les files de messages possèdent un système de priorité.
  • Les sémaphores POSIX sont relativement simples à manipuler.
  • L'interface est standardisée par POSIX.

19. Points importants à retenir

Les trois principales familles IPC POSIX sont :
  • Message queues.
  • Semaphores.
  • Shared memory.
Les fonctions principales sont :

Code: Select all

mq_open()
mq_send()
mq_receive()
mq_close()
mq_unlink()

sem_open()
sem_wait()
sem_post()
sem_close()
sem_unlink()

shm_open()
ftruncate()
mmap()
munmap()
close()
shm_unlink()
Un nom IPC POSIX commence généralement par :

Code: Select all

/
Exemple :

Code: Select all

"/inside_the_system"
O_CREAT permet de créer l'objet s'il n'existe pas.

O_EXCL combiné avec O_CREAT permet d'échouer si l'objet existe déjà.

Fermer un objet ne signifie pas nécessairement supprimer son nom.

Les opérations :

Code: Select all

mq_unlink()
sem_unlink()
shm_unlink()
servent à supprimer le nom de l'objet.

La mémoire partagée POSIX utilise mmap(), contrairement à la mémoire partagée System V qui utilise principalement shmat().

Les sémaphores POSIX utilisent principalement sem_wait() et sem_post(), alors que System V utilise notamment semop().

Les files de messages POSIX utilisent des priorités, tandis que System V repose notamment sur le champ mtype.


20. Résumé

POSIX IPC est une famille de mécanismes de communication et de synchronisation entre processus.

Elle fournit :
  • des files de messages ;
  • des sémaphores ;
  • de la mémoire partagée.
L'API POSIX reprend plusieurs concepts déjà présents dans l'API Unix classique, notamment les noms d'objets, les flags O_CREAT et O_EXCL, les permissions et, pour la mémoire partagée, les descripteurs de fichiers et mmap().

Par rapport à System V IPC, l'interface POSIX est souvent plus cohérente et plus facile à intégrer avec les autres mécanismes Unix.

Les chapitres suivants permettent ensuite d'étudier séparément et plus en profondeur les files de messages POSIX, les sémaphores POSIX et la mémoire partagée POSIX.

Who is online

Users browsing this forum: No registered users and 0 guests