[LINUX] Verwenden Sie gemeinsam genutzten Speicher mit gemeinsam genutzten Bibliotheken

Ich wollte die Daten in der gemeinsam genutzten Bibliothek zwischen den Prozessen teilen, die sie anhängen, und ich habe verschiedene Versuche und Fehler gemacht, aber ich war ein wenig süchtig danach, also werde ich sie als Artikel schreiben.

Globale Variablen in einer gemeinsam genutzten Bibliothek

Im Gegensatz zu Windows-DLLs werden gemeinsam genutzte UNIX-basierte Bibliotheken im Speicherbereich jedes Prozesses abgelegt, auch wenn Variablen im globalen Bereich abgelegt sind. Daher kann die Kommunikation zwischen Prozessen nicht einfach mithilfe der gemeinsam genutzten Bibliothek durchgeführt werden. Der einfachste Weg, die von der gemeinsam genutzten Bibliothek verwendeten Daten gemeinsam zu nutzen, ist die Verwendung des gemeinsam genutzten Speichers. Hier ist also der Beispielcode.

lib_shared_memory.c


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

static void *sharedmemory; //Zeiger auf gemeinsam genutzten Speicher
static int seg_id;         //Shared Memory ID
static int* pnumattachproc;//Anzahl der an den gemeinsam genutzten Speicher angeschlossenen Prozesse(Auf gemeinsam genutzten Speicher gelegt)

__attribute__ ((constructor))
void attach_shmem(void)
{
    int isfirstproc = 0;
    key_t key = 10;
    size_t size = 1000;
    //Erstellen Sie einen gemeinsamen Speicher
    seg_id = shmget(key, size, IPC_CREAT | IPC_EXCL | 0660);
    //Konnte nicht erstellt werden,Und wenn es einen gemeinsamen Speicher mit demselben Schlüssel gibt
    if ((seg_id == -1) && (errno == EEXIST)){
        //Holen Sie sich die ID dieses gemeinsam genutzten Speichers
        seg_id = shmget(key, size, 0);
    }else if(seg_id > 0){
        //Wenn der gemeinsam genutzte Speicher erfolgreich erstellt wurde, setzen Sie ein Flag, um die Initialisierungsverarbeitung durchzuführen.
        isfirstproc = 1;
    }
    if (seg_id == -1)
        exit(1);
    //Gemeinsamen Speicher anhängen
    sharedmemory = shmat(seg_id, NULL, 0);
    if(isfirstproc){
        pnumattachproc = (int*)sharedmemory;
        //Initialisieren Sie die Anzahl der angehängten Prozesse
        *pnumattachproc = 0;
    }
    (*pnumattachproc)++; //Erhöhen Sie die Anzahl der angehängten Prozesse
}

__attribute__ ((destructor))
void detach_shmem(void)
{
    (*pnumattachproc)--; //Verringern Sie die Anzahl der angehängten Prozesse
    if(*pnumattachproc == 0){
        //Wenn die Anzahl der angehängten Prozesse 0 erreicht,
        //Geben Sie dem gemeinsam genutzten Speicher das Release-Attribut
        shmctl(segid, IPC_RMID, NULL);    
    }
    //Shared Memory trennen
    (void) shmdt(sharedmemory);
}

int get_attachproc_num(void){
    return *pnumattachproc;
}

Der Build verwendet die Optionen für gemeinsam genutzte Bibliotheken.

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

Als Einschränkung

shmctl(segid, IPC_RMID, NULL); 

Lassen Sie uns ausführen, nachdem der angehängte Prozess 0 geworden ist und die Freigabe bestätigt wurde. Wenn Sie es ausführen, wenn der angehängte Prozess vorhanden ist und ein neuer Prozess versucht, eine Verbindung zum gemeinsam genutzten Speicher herzustellen, wird ein neuer gemeinsam genutzter Speicher erstellt, obwohl er denselben Schlüssel hat. Um dies zu verhindern, wird die Anzahl der an den gemeinsam genutzten Speicher angeschlossenen Prozesse verwaltet, indem sie als Variable im gemeinsam genutzten Speicher abgelegt werden, sodass der Prozess zum Trennen der gemeinsam genutzten Bibliothek am Ende freigegeben werden kann.

Ich habe das nicht verstanden, ich habe beim Erstellen des gemeinsam genutzten Speichers eine Freigabeanforderung hinzugefügt und konnte keine Verbindung zum gemeinsam genutzten Speicher herstellen.

das ist alles.

Recommended Posts

Verwenden Sie gemeinsam genutzten Speicher mit gemeinsam genutzten Bibliotheken
Debuggen Sie gemeinsam genutzte Bibliotheken mit VScode
[IOS] Verwenden Sie gemeinsam genutzte Blätter mit Pythonista3.
Verwenden Sie mecab-ipadic-neologd mit igo-python
Verwenden Sie RTX 3090 mit PyTorch
Verwenden Sie ansible mit cygwin
Verwenden Sie pipdeptree mit virtualenv
Speichern Sie Speicher mit `` __slots__``
[Python] Verwenden Sie JSON mit Python
Verwenden Sie Mock mit Pytest
Verwenden Sie den Indikator mit pd.merge
Verwenden Sie Gentelella mit Django
Verwenden Sie Mecab mit Python 3
Verwenden Sie Tensorboard mit Chainer
Kommunikation zwischen Prozessen ~ gemeinsamer Speicher ~
Verwenden Sie DynamoDB mit Python
Verwenden Sie pip mit MSYS2
Verwenden Sie Python 3.8 mit Anaconda
Verwenden Sie Copyright mit Spacemacs
Verwenden Sie Python mit Docker
Verwenden Sie TypeScript mit Django-Kompressor
Verwenden Sie WENIGER mit Django
Gemeinsamer Speicher zwischen Prozessen
Verwenden Sie MySQL mit Django
Verwenden Sie Enum mit SQLAlchemy
Verwenden Sie Tensorboard mit NNabla
Verwenden Sie GPS mit Edison
Verwenden Sie nim mit Jupyter
Verwenden Sie die Trello-API mit Python
Verwenden Sie benutzerdefinierte Tags mit PyYAML
Verwenden Sie Richtungsdiagramme mit networkx
Verwenden Sie TensorFlow mit Intellij IDEA
Verwenden Sie die Twitter-API mit Python
Verwenden Sie pip mit Jupyter Notebook
Fehler beim Laden von gemeinsam genutzten Bibliotheken
Verwenden Sie DATE_FORMAT mit dem SQLAlchemy-Filter
Verwenden Sie TUN / TAP mit Python
Verwenden Sie sqlite3 mit NAO (Pepper)
Verwenden Sie die load_extensions von sqlite mit Pyramid
Verwenden Sie Windows 10-Schriftarten mit WSL
Installieren Sie eine externe Bibliothek mit Python
Verwendung von Chainer mit Jetson TK1
Verwenden Sie SSL mit Sellerie + Redis
Verwenden Sie Cython mit Jupyter Notebook
Verwenden Sie Maxout + CNN mit Pylearn2
Verwenden Sie WDC-433SU2M2 mit Manjaro Linux
Verwenden Sie OpenBLAS mit numpy, scipy
Untersuchen Sie Speicherlecks mit objgraph
Verwenden Sie die Unterschall-API mit Python3
Verwenden von Sonicwall NetExtener mit Systemd
Verwenden Sie prefetch_related bequem mit Django
Verwenden Sie einen AWS-Interpreter mit Pycharm
Verwenden von Bokeh mit IPython Notebook
Verwenden Sie Python-ähnliche Bereiche mit Rust
Verwenden Sie pyright mit CentOS7, emacs lsp-mode
Python: So verwenden Sie Async mit
Verwenden der SQL-Datenbank von Azure mit SQL Alchemy
Verwenden Sie eine Point Grey-Kamera mit Python (PyCapture2).
Verwenden Sie vl53l0x mit RaspberryPi (Python)
Verwenden Sie PX-S1UD / PX-Q1UD mit Jetson Nano