Comment synchroniser l’access à la mémoire partagée dans LynxOS / POSIX?

J’implémente deux processus sur un système LynxOS SE (conforme à POSIX) qui communiquera via la mémoire partagée.

Un processus agira en tant que “producteur” et l’autre en “consommateur”. Dans un système multi-thread, mon approche consiste à utiliser un couple mutex et condvar (variable de condition), le consommateur attend le condvar (avec pthread_cond_wait ) et le producteur le signalant (avec pthread_cond_signal ) lorsque la mémoire partagée est mise à jour. .

Comment y parvenir dans une architecture multi-processus plutôt que multi-threadée?

Existe-t-il un moyen LynxOS / POSIX pour créer une paire condvar / mutex pouvant être utilisée entre processus?
Ou un autre mécanisme de synchronisation est-il plus approprié dans ce scénario?

La méthode standard pour créer un processus partagé mutex / cond. variable consiste à les initialiser avec un atsortingbut dans lequel vous définissez pthread_mutexattr_setpshared / pthread_condattr_setpshared. Vérifiez si LynxOS prend en charge cela.

Vous aurez naturellement besoin de placer de tels mutex / cond. variables dans la mémoire partagée en quelque sorte, de sorte que tous les processus peuvent l’utiliser.

Le mérite en revient à @nos, mais j’aimerais développer un peu sa réponse.
En fin de compte (en excluant le traitement des erreurs pour plus de clarté), j’ai procédé comme suit:

1. Définir la structure de la mémoire partagée

Celui-ci contient les objects de synchronisation interprocessus et les données à partager.

 typedef struct { // Synchronisation objects pthread_mutex_t ipc_mutex; pthread_cond_t ipc_condvar; // Shared data int number; char data[1024]; } shared_data_t; 

2. Créer la mémoire partagée et définir la taille (processus maître)

Sur le processus maître, créez un nouvel object de mémoire partagée:

 fd = shm_open(SHAREDMEM_FILENAME, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR); ftruncate(fd, sizeof(shared_data_t)); 

2. OU Ouvrez la mémoire partagée (processus esclave)

Sur l’esclave, attachez-le simplement à un object existant:

 fd = shm_open(SHAREDMEM_FILENAME, O_RDWR, S_IRUSR|S_IWUSR); 

3. Mapper dans l’espace processus

 shared_data_t* sdata = (shared_data_t*)mmap(0, sizeof(shared_data_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); close(fd); 

4. Initiez les variables de synchronisation (processus maître uniquement).

 pthread_mutexattr_t mutex_attr; pthread_mutexattr_init(&mutex_attr); pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED); pthread_mutex_init(&sdata->ipc_mutex, &mutex_attr); pthread_condattr_t cond_attr; pthread_condattr_init(&cond_attr); pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED); pthread_cond_init(&sdata->ipc_condvar, &cond_attr); 

C’est tout.

Mutex et cond peuvent maintenant être utilisés normalement pour contrôler l’access aux données partagées.

Les seuls pièges réels sont de s’assurer que le processus maître a créé la mémoire partagée et initialisé les variables de synchronisation avant le démarrage du processus esclave. Et assurez-vous de bien ranger munmap() et shm_unlink() selon vos besoins.

Remarque: Alternative XSI

L’extension POSIX: XSI possède d’autres fonctions de partage de mémoire ( shmget() , shmat() etc.) qui peuvent s’avérer plus utiles si elles sont disponibles, mais elles ne sont pas dans la version de LynxOS-SE que j’utilise.

Ceci est fait avec des sémaphores POSIX non nommés , c’est-à-dire que les sémaphores eux-mêmes sont placés dans la mémoire partagée.

Vous pouvez y parvenir avec la mémoire partagée / sémaphore IPC.

Voici un article avec un bel exemple:

http://www-personal.washtenaw.cc.mi.us/~chasselb/linux275/ClassNotes/ipc/shared_mem.htm