2017-02-22 2 views
0

In Anwendung 1 (C-Code) im mit einem gemeinsam genutzten Speicher wie folgt zu erstellen:Attach vorhandenen Shared Memory mit QSharedMemory

char * key_path = "/tmp/shmem"; 

int file = open(key_path, O_CREAT | O_RDWR | O_APPEND, 0755); 
close(file); 
key_t key = ftok(key_path, 1); 

shmid = shmget (key, SHM_DATASIZE , IPC_CREAT | SHM_R | SHM_W); 
shmdata = shmat(shmid, NULL, 0);shmid); 

In Anwendung 2 (QT) Ich mag dieses Shared

const char* native_key = "/tmp/shmem"; 

key_t ft_key = ftok(native_key, 1); 
key = QString::number(ft_key); 

QSharedMemory shmem(key); 
if(!shmem.attach()) { 
    qDebug() << "attach failed" << shmem.errorString() << shmem.key() << shmem.nativeKey() << endl; 
} 
zugreifen möchten

attach fehlgeschlagen "QSharedMemory :: attach (shmget): existiert nicht" "16858191" "/ tmp/qipc_sharedmemory_24384b85e5d54b23bd4f84f14de71b10d4801666"

Also versuchte ich habe die folgende

const char* native_key = "/tmp/shmem"; 

key_t ft_key = ftok(native_key, 1); 
key = QString::number(ft_key); 

QSharedMemory shmem(key); 
shmem.setNativeKey(native_key); 
if(!shmem.attach()) { 
    qDebug() << "attach failed" << shmem.errorString() << shmem.key() << shmem.nativeKey() << endl; 
} 

attach fehlgeschlagen "QSharedMemory :: attach (shmget): existiert nicht" "" "/ tmp/shmem_prot"

Ich habe einen Blick auf die Quelle von qsharedmemory_unix.cpp

Ich denke, das Problem ist, dass unix_key nicht gesetzt ist, so dass shmget in attach() fehlschlagen wird. handle() ist privat, daher kann ich diese Funktion nicht aufrufen, um den unix_key zu setzen.

Ist es möglich, auf den Shared Memory zuzugreifen, ohne die Größe zu kennen/create() aufzurufen?

Wenn ich versuche, erstellen zu nennen()

QSharedMemory shmem(key); 
shmem.create(SHM_DATASIZE); 

ein neues Shared Memory wird erstellt ...

Was mache ich falsch? Danke im Voraus.

+0

gibt es 2 Dinge, die ich denke, könnte Probleme verursachen. Erstens, lösen Sie die Erinnerung, wenn Sie damit fertig sind? Zweitens: Verwenden Sie Semaphor-Signale, um Mehrfachzugriff auf den Speicher zu verhindern? und für die Befestigung kenne ich keine Funktion, die Sie verwenden können, die die Größe des Bereichs nicht benötigt.Aber "vielleicht" können Sie versuchen, einen anderen Bereich mit nur einer Ganzzahl (oder etwas) zu erstellen, um die Größe des ersten zu halten. Und benutze es, um es danach zu befestigen. viel Glück – koksalb

+0

Welches Betriebssystem? Angenommen, Sie haben das Dienstprogramm "ipcs", was ist die Ausgabe von "ipcs-a"? Das sollte alle SysV Shared Memory-Segmente auf Ihrem Computer anzeigen. –

+0

@koksalb Wir können über das Trennen und Semaphoren sprechen, wenn der Shared Memory erfolgreich angehängt wurde. Aber in diesem Zustand spielt das keine Rolle. – mvollmer

Antwort

1

Sie greifen nicht auf dasselbe gemeinsame Speichersegment zu. Qt ändert den Schlüssel, den Sie übergeben, und das Ergebnis ist ein anderer Schlüssel und daher eine gemeinsame Speicher-ID.

Per the QSharedMemory documentation:

Warnung: QSharedMemory ändert den Schlüssel in einer Qt-spezifische Art und Weise, sofern nicht anders angegeben. Die Interoperation mit Nicht-Qt-Anwendungen wird erreicht, indem zuerst ein gemeinsamer Standardspeicher mit QSharedMemory() erstellt und dann ein systemeigener Schlüssel mit setNativeKey() festgelegt wird. Bei Verwendung systemeigener Schlüssel ist der gemeinsam genutzte Speicher nicht gegen Mehrfachzugriffe geschützt (z. B. lock() nicht möglich) und ein benutzerdefinierter Mechanismus sollte verwendet werden, um einen solchen Schutz zu erreichen.

Es scheint, dass Sie das Shared-Memory-Segment mit QSharedMemory zu schaffen, müssen Sie einen neuen Schlüssel gesetzt setNativeKey() verwendet, dann auf diesen Speicher von außerhalb QSharedMemory befestigen.

+0

Vielen Dank, dass Sie darauf hingewiesen haben. Aber das funktioniert nicht. 'setNativeKey()' löst den neu erstellten Shared Memory. 'QSharedMemory shmem (Schlüssel); shmem.create (SHM_DATASIZE); shmem.setNativeKey (native_key); ' So scheint es, dass es nicht möglich ist, auf freigegebene Speicher zuzugreifen, die nicht von QSharedMemory erstellt wurden. Die einzige Möglichkeit besteht darin, ein SharedMemory mit QSharedMemory zu erstellen und von einer anderen Anwendung darauf zuzugreifen. Das ist irgendwie komisch. – mvollmer

+0

@mvollmer Wenn Sie den tatsächlichen Schlüssel aus dem 'QSharedMemory'-Segment abrufen und an Ihre Nicht-Qt-Anwendung übergeben können, sollte diese Anwendung diesen Schlüssel direkt verwenden können. Sobald Sie das Segment in Qt erstellt haben, [können Sie 'ipcs -m'] (http://man7.org/linux/man-pages/man1/ipcs.1.html) verwenden, um Details zu allen Shared-Memory-Segmenten anzuzeigen. –