Ich möchte eine Variable zwischen mehreren unabhängigen C-Executables in Linux teilen. Das heißt, ein Programm wird auf ein Array schreiben und ein Flag setzen, so dass kein anderes Programm es benutzen kann, und nach diesem Vorgang wird es das Flag aufheben und dann wird ein anderes Programm das Array lesen. Ich habe versucht, die gleiche benutzerdefinierte Header-Datei (enthält die Variable) in jedem Programm, aber es scheint verschiedene Instanzen der Variablen erstellt werden, wenn die Programme aufgerufen werden.Gemeinsame Nutzung derselben Variablen zwischen mehreren unabhängigen Programmen in Linux
Antwort
Variablen, die Sie in Ihren Kopfzeilen deklarieren, erzeugen eine Kopie, wo auch immer Sie sie einschließen (unless you declare them extern
). Bei getrennten Prozessen wird natürlich jeder Prozess seinen eigenen Speicherplatz haben. Sie müssen komplexere Techniken verwenden, um dies zu umgehen, d. H. Inter Process Communication (IPC). Zum Beispiel:
- (genannt) Pipes
- Sockets
- Shared Memory
Ihre Frage wie shared memory liest, was Sie wollen, da hierdurch mehrere Prozesse die gleichen Speicherbereiche zugreifen teilen einige Variablen. Vielleicht werfen Sie einen Blick auf this question und seine Antworten für ein Beispiel.
Ihr Programm wäre erforderlich, um einen gemeinsamen Speicher zu erstellen, z. Verwenden Sie shmget und das freigegebene Speicherobjekt mit shmat anhängen. Wenn mehrere Prozesse auf dieselben Speicherbereiche zugreifen, ist es immer ein gesunder Ansatz, eine Prozesssynchronisierung während des Lese-/Schreibvorgangs für die Variable hinzuzufügen, z. Verwenden eines gemeinsamen Semaphors (semget, semop).
Wenn Sie mit Ihrem gemeinsamen Speicher fertig sind, müssen Sie (shmdt) davon trennen. Dadurch teilen Sie dem Kernel mit, dass Ihr Prozess keinen Zugriff mehr darauf benötigt. Der Prozess, der das Shared Memory/Semaphore-Objekt erstellt hat, muss diese auch am Ende Ihrer Programme zerstören. Andernfalls wird es im Speicher verbleiben, wahrscheinlich bis Sie Ihren Rechner neu starten (siehe shmctl, semctl, insbesondere IPC_RMID
).
Beachten Sie, dass für Shared Memory-Objekte "Das Segment wird nur tatsächlich zerstört werden, nachdem der letzte Prozess es trennt". Sie möchten also sicherstellen, dass dies tatsächlich für alle Ihre Prozesse geschieht (shmdt).
Als Reaktion auf die Kommentare, hier ist der POSIX-Ansatz:
System V Shared Memory (shmget (2), shmop (2), etc.) ist ein älterer Shared-Memory-API. Der gemeinsame POSIX-Speicher bietet eine einfachere und besser gestaltete Oberfläche; Auf der anderen Seite ist der POSIX-Shared-Speicher (insbesondere auf älteren Systemen) etwas weniger verfügbar als der Shared Memory von System V.
- shm_open - zu erhalten, einen Zeiger auf den Speicher
- sem_open - -
- mmap die Größe des gemeinsamen Speichers zu setzen - in dem Speicher (über Dateideskriptor)
- ftruncate erhalten geteilt erhalten Sie ein Semaphor
- sem_wait, sem_post - für Ihre Lese-/Schreib-Synchronisation
- shm_unlink, sem_close - aufzuräumen, nachdem alle
Siehe this overview und here auch für Beispiele.
Schließlich ist zu beachten, dass
POSIX Shared-Memory-Objekte Kernel Persistenz haben: ein Shared-Memory-Objekt vorhanden ist, bis das System heruntergefahren wird, oder bis alle Prozesse unmapped haben die Aufgabe, und es wird mit shm_unlink gelöscht (3)
um Berücksichtigung der Persistenz der Shared-Memory-Objekte zu nehmen, vergessen Sie nicht, Signal-Handler Ihrer Anwendung hinzufügen, dass die Reinigungsarbeiten im Fall einer Ausnahme durchführen wird al Kündigung (SIGINT, SIGTERM usw.).
Verwenden Sie nicht 'shmget', verwenden Sie stattdessen die Posix' shm_open'. das ist viel weniger schmerzhaft zu verwenden, und haben nicht das Problem der Schlüssel Kollisionen – Hasturkun
@Hasturkun - Danke für den Kommentar! Ich habe diese bisher noch nicht verwendet, aber ich habe einen Hinweis darauf zur Vollständigkeit hinzugefügt. – moooeeeep
Danke mooeeeeep. –
Blick in POSIX Shared Memory über shm_open
und shm_unlink
... Ich fühle mich persönlich sind sie leichter zu bedienen und gerade nach vorne als die älteren System-V-IPC ruft wie shmget
usw., da der Griff Arbeiten wieder genau wie ein Dateideskriptor, den Sie mit Aufrufen wie read
, write
usw. verwenden können. Wenn Sie andernfalls über normale Zeiger auf das gemeinsam genutzte Speicherobjekt des Dateideskriptors zugreifen möchten, können Sie mmap
für den von shm_open
zurückgegebenen Dateideskriptor verwenden .
Hinweis: IPC (Interprozesskommunikation), es ist ein zu großes Thema in einer Antwort hier anzusprechen. – Nim
Ja, vielleicht sollten Sie [hier] (http://en.wikipedia.org/wiki/Inter-process_communication) nachsehen. Zwei unabhängige ausführbare Dateien werden in verschiedenen Prozessen gestartet, daher müssen Sie eine Art von Kommunikation zwischen ihnen implementieren, indem Sie [Sockets] verwenden (http://www.cs.cf.ac.uk/Dave/C/node28.html) , [rohre] (http://www.cs.cf.ac.uk/Dave/C/node23.html), etc ... oder sogar Dateien. –
Ich verstehe. Das heißt, in diesem Fall muss eine Rohrleitung verwendet werden. Gibt es einen einfacheren Weg? –