Ein einfaches C++ - shared-memory-Programm, das auf linux: segmentation fault
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
struct LOCK {
string name;
string type;
vector <string> pids;
};
int main ()
{
int segment_id;
LOCK* shared_memory;
struct shmid_ds shmbuffer;
int segment_size;
const int shared_segment_size = 0x6400;
/* Allocate a shared memory segment. */
segment_id = shmget (IPC_PRIVATE, shared_segment_size,
IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
/* Attach the shared memory segment. */
shared_memory = (LOCK*) shmat (segment_id, 0, 0);
printf ("shared memory attached at address %p\n", shared_memory);
/* Determine the segment's size. */
shmctl (segment_id, IPC_STAT, &shmbuffer);
segment_size = shmbuffer.shm_segsz;
printf ("segment size: %d\n", segment_size);
/* Write a string to the shared memory segment. */
//sprintf (shared_memory, "Hello, world.");
shared_memory -> name = "task 1";
shared_memory -> type = "read";
(shared_memory -> pids).push_back("12345");
(shared_memory -> pids).push_back("67890");
/* Detach the shared memory segment. */
shmdt (shared_memory);
/* Reattach the shared memory segment, at a different address. */
shared_memory = (LOCK*) shmat (segment_id, (void*) 0x5000000, 0);
printf ("shared memory reattached at address %p\n", shared_memory);
/* Print out the string from shared memory. */
//printf ("%s\n", shared_memory -> name);
cout << "Name of the shared memory: " + shared_memory -> name << endl;
/* Detach the shared memory segment. */
shmdt (shared_memory);
/* Deallocate the shared memory segment. */
shmctl (segment_id, IPC_RMID, 0);
return 0;
}
Ich habe den code aus einem tutorial auf shared memory. Es funktionierte, bis ich den vorgegebenen struct LOCK und versucht zu schreiben Sperren anstelle von char* in der shared-memory.
Könnte jemand bitte mir helfen herauszufinden, das problem ist hier, dass das "segmentation fault"?
Erfahren Sie, kompilieren Sie alle Warnungen aktiviert und der debug-Informationen (d.h.
wenn Sie mit string und vector-ähnliche Strukturen im shared memory ist notwendig, der beste Weg ist die Verwendung von statischen arrays in struct LOCK.
g++ -Wall -g
). Verwenden Sie dann Ihre gdb
debugger, um herauszufinden, wo die SEGV-Fehler.wenn Sie mit string und vector-ähnliche Strukturen im shared memory ist notwendig, der beste Weg ist die Verwendung von statischen arrays in struct LOCK.
InformationsquelleAutor Terry Li | 2011-11-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
Stellen Sie
vector
s undstring
s in den shared memory. Beide dieser Klassen zuordnen Erinnerung an Ihre eigene, die zugeteilt werden, die innerhalb des Adressraums von welchem Prozess erzeugt die Zuweisung, und produziert einen segfault, wenn der Zugriff aus dem anderen Verfahren. Sie könnten versuchen, unter Angabe allocators zu verwenden, shared memory, aber da in C++03 allocators angenommen werden zu Staatenlosen ich bin mir nicht sicher, ob es möglich sein wird.Überprüfen Sie heraus, wie Boost.Prozessübergreifende tut es.
nicht das OS blendet aus, dass die userspace-Programme?
Nein. Wie könnte es? Wenn Sie die Karte shared memory an der Adresse X, dann den Mauszeiger auf ein Objekt in es wird werden X+A (wobei A der relative offset). Wenn ein anderer Prozess-maps, shared memory an der Adresse Y (weil X im Einsatz war, in diesem Prozess, oder einfach nur Pech), muss es einen Zeiger auf Y+A, um auf die gleichen Daten zugreifen. Sie können nicht einfach die absolute Zeiger (X+A) von einem Prozeß zu einem anderen, oder legen Sie Sie in den shared memory. Sie müssen übergeben Sie die relative Zeiger (A) und jeder Prozess muss seine Basis-mapping-Adresse auf die Zeiger, bevor er dereferenziert.
Du hast Recht, habe ich falsch verstanden.
InformationsquelleAutor K-ballo
Haben Sie eine Reihe von Problemen. Der offensichtlichste Vorteil ist, dass Sie nicht konstruieren Ihr Objekt. In der undurchsichtigen form, Sie sind derzeit dabei:
Was Sie tun sollten, ist es zumindest sehr:
(Ersetzen Sie einfach
Foo
durchLOCK
für Ihre situation.)Jedoch wird es komplizierter:
vector
undstring
erfordern dynamische Zuordnungen selbst. Dieser Speicher muss im gleichen Adressraum wie IhrLOCK
. So der standard-Weg, dies zu lösen, ist zu schreiben, Ihre eigenen allocator und pass auf:Schließlich, Sie haben zu schreiben, eine konforme allocator-Klasse, versetzt den Speicher in den gleichen Adressraum wie die eine, in der Ihre
LOCK
- Objekt wird letztendlich gehen:Die Zuweisung zu erwarten wäre, sich darum zu kümmern, nicht? Die neue stateful allocators sollte das Leben viel einfacher, als Sie jetzt das speichern einer Basisadresse.
Nicht wirklich sicher. Vielleicht, wenn die Zuweisung hat eine nicht-Zeiger-Zeiger-Typ...
Allocators erhebliche Freiheit zu definieren, was Sie bitte ein "Zeiger-Typ"... ich bin mir ziemlich sicher, dass dies könnte werden manipuliert bis.
In C++11,, ja, ich denke, es kann möglich sein, es zu erreichen...
InformationsquelleAutor Kerrek SB
Ich weiß, es ist sehr lange her. Aber ich war auf der Suche nach how-to (erinnern) über shared mem und dieser thread ist interessant.
Meine Zwei Cent zu dem demander :
Shared-Memory-ID == file_handle von open(...);
Ja..., Wie Sie KORREKT serialisieren und dann Lesen-schreiben std::string oder auch std::vector in eine DATEI ? Tun Sie wirklich 'erweitern/verkleinern' std::string oder std::vector aus innerhalb einer DATEI ??
Danke 🙂
InformationsquelleAutor Bretzelus