[LINUX] Utiliser la mémoire partagée avec une bibliothèque partagée

Je voulais partager les données de la bibliothèque partagée entre les processus qui l'attachent, et j'ai fait divers essais et erreurs, mais j'en étais un peu accro, je vais donc l'écrire sous forme d'article.

Variables globales sur une bibliothèque partagée

Contrairement aux DLL Windows, les bibliothèques partagées UNIX sont placées dans l'espace mémoire de chaque processus même si les variables sont placées dans l'espace global, de sorte que la communication inter-processus ne peut pas être effectuée simplement en utilisant la bibliothèque partagée. Le moyen le plus simple de partager les données utilisées par la bibliothèque partagée consiste à utiliser la mémoire partagée. Voici donc l'exemple de code.

lib_shared_memory.c


#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/shm.h>

static void *sharedmemory; //Pointeur vers la mémoire partagée
static int seg_id;         //ID de mémoire partagée
static int* pnumattachproc;//Nombre de processus attachés à la mémoire partagée(Placé sur la mémoire partagée)

__attribute__ ((constructor))
void attach_shmem(void)
{
    int isfirstproc = 0;
    key_t key = 10;
    size_t size = 1000;
    //Créer une mémoire partagée
    seg_id = shmget(key, size, IPC_CREAT | IPC_EXCL | 0660);
    //Échec de la création,Et s'il y a une mémoire partagée avec la même clé
    if ((seg_id == -1) && (errno == EEXIST)){
        //Obtenez l'identifiant de cette mémoire partagée
        seg_id = shmget(key, size, 0);
    }else if(seg_id > 0){
        //Si la mémoire partagée est créée avec succès, définissez un indicateur pour effectuer le traitement d'initialisation.
        isfirstproc = 1;
    }
    if (seg_id == -1)
        exit(1);
    //Joindre de la mémoire partagée
    sharedmemory = shmat(seg_id, NULL, 0);
    if(isfirstproc){
        pnumattachproc = (int*)sharedmemory;
        //Initialiser le nombre de processus attachés
        *pnumattachproc = 0;
    }
    (*pnumattachproc)++; //Augmenter le nombre de processus attachés
}

__attribute__ ((destructor))
void detach_shmem(void)
{
    (*pnumattachproc)--; //Décrémenter le nombre de processus attachés
    if(*pnumattachproc == 0){
        //Si le nombre de processus attachés atteint 0,
        //Donnez à la mémoire partagée l'attribut release
        shmctl(segid, IPC_RMID, NULL);    
    }
    //Détachement de la mémoire partagée
    (void) shmdt(sharedmemory);
}

int get_attachproc_num(void){
    return *pnumattachproc;
}

La construction utilise les options des bibliothèques partagées.

gcc -fPIC -shared -o libshm.so lib_shared_memory.c

En guise de mise en garde

shmctl(segid, IPC_RMID, NULL); 

Exécutons une fois que le processus attaché devient 0 et que la version est confirmée. Si vous l'exécutez lorsque le processus attaché existe, lorsqu'un nouveau processus tente de se connecter à la mémoire partagée, il créera une nouvelle mémoire partagée même si elle a la même clé. Pour éviter cela, le nombre de processus attachés à la mémoire partagée est géré en le plaçant comme variable sur la mémoire partagée afin que le processus de détachement final de la bibliothèque partagée puisse être libéré.

Je n'ai pas compris cela, j'ajoutais une demande de libération lors de la création de la mémoire partagée et je n'ai pas pu m'attacher à la mémoire partagée.

c'est tout.

Recommended Posts

Utiliser la mémoire partagée avec une bibliothèque partagée
Déboguer les bibliothèques partagées avec VScode
[IOS] Utilisez des feuilles partagées avec Pythonista3.
Utilisez mecab-ipadic-neologd avec igo-python
Utilisez RTX 3090 avec PyTorch
Utiliser ansible avec cygwin
Utiliser pipdeptree avec virtualenv
Économisez de la mémoire avec `` __slots__``
[Python] Utiliser JSON avec Python
Utilisez Mock avec pytest
Utiliser l'indicateur avec pd.merge
Utiliser Gentelella avec Django
Utiliser mecab avec Python 3
Utiliser tensorboard avec Chainer
Communication inter-processus ~ mémoire partagée ~
Utiliser DynamoDB avec Python
Utiliser pip avec MSYS2
Utilisez Python 3.8 avec Anaconda
Utiliser les droits d'auteur avec Spacemacs
Utiliser python avec docker
Utiliser TypeScript avec django-compresseur
Utilisez LESS avec Django
Mémoire partagée entre les processus
Utiliser MySQL avec Django
Utiliser Enum avec SQLAlchemy
Utiliser tensorboard avec NNabla
Utiliser le GPS avec Edison
Utilisez nim avec Jupyter
Utiliser l'API Trello avec python
Utiliser des balises personnalisées avec PyYAML
Utiliser des graphiques directionnels avec networkx
Utiliser TensorFlow avec Intellij IDEA
Utiliser l'API Twitter avec Python
Utiliser pip avec Jupyter Notebook
erreur lors du chargement des bibliothèques partagées
Utiliser DATE_FORMAT avec le filtre SQLAlchemy
Utiliser TUN / TAP avec Python
Utilisez sqlite3 avec NAO (Pepper)
Utilisez les load_extensions de sqlite avec Pyramid
Utiliser les polices Windows 10 avec WSL
Installer une bibliothèque externe avec Python
Utilisation du chainer avec Jetson TK1
Utiliser SSL avec Celery + Redis
Utiliser Cython avec Jupyter Notebook
Utilisez Maxout + CNN avec Pylearn2
Utilisez WDC-433SU2M2 avec Manjaro Linux
Utilisez OpenBLAS avec numpy, scipy
Rechercher les fuites de mémoire avec objgraph
Utiliser l'API subsonique avec python3
Utilisation de Sonicwall NetExtener avec Systemd
Utilisez prefetch_related commodément avec Django
Utiliser l'interpréteur AWS avec Pycharm
Utilisation de Bokeh avec IPython Notebook
Utiliser une plage de type Python avec Rust
Utiliser pyright avec CentOS7, emacs lsp-mode
Python: comment utiliser async avec
Utilisation de la base de données SQL d'Azure avec SQL Alchemy
Utiliser la caméra Point Grey avec Python (PyCapture2)
Utilisez vl53l0x avec RaspberryPi (python)
Utilisez PX-S1UD / PX-Q1UD avec Jetson nano