2014-01-24 16 views
8

Ich wollte nur wissen, wo Shared Memory in einem Linux-System residiert? Ist es im physischen Speicher oder virtuellen Speicher?Wo befindet sich der freigegebene Linux-Speicher?

Ich bin mir bewusst über die virtuelle Speicher Send Box des Prozesses, sie sind unterschiedlich von Prozess zu Prozess und Prozesse sehen nicht gegenseitig Speicher, aber wir können die Daten zwischen Prozessen mit IPC übergeben. Um das einfache Szenario zu implementieren, habe ich gerade ein einfaches Shared-Memory-Programm erstellt und versuche, die Shared-Memory-Adresse und Wert Rückgabe von shmat Funktion, aber beide Prozesse haben unterschiedliche Adresse, aber gleichen Wert.

Hier ist das Schreibprogramm.

write.c

#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <stdio.h> 

int main() { 

    key_t key=1235; 
    int shm_id; 
    void *shm; 

    int *ptr = 83838; 

    shm_id = shmget(key,10,IPC_CREAT | 0666); 
    shm = shmat(shm_id,NULL,NULL); 

    sprintf(shm,"%d",ptr); 

    printf("Address is %p, Value is %p \n", (void *)shm, (void *)&ptr); 
    printf("Shm value is %d \n", *(int *)shm); 
    return; 
} 

Hier ist das Leseprogramm.

read.c

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

int main() { 

    key_t key=1235; 
    int shm_id; 
    void *shm; 

    int *p = (int *)malloc(sizeof(int)); 
    shm_id = shmget(key,10,NULL); 
    shm = shmat(shm_id,NULL,NULL); 
    if(shm == NULL) 
    { 
    printf("error"); 
    } 
    sscanf(shm,"%d",p); 
    printf("Address is %p %p %p %d\n",(void *)shm, (void *)p, (void *)&p, *p); 
    printf("Shared value is %d \n", *(int *)shm); 
    return 0; 
} 

Es wäre toll, wenn jemand im Detail erklären bitte könnte, wie die Prozesse den gleichen Wert sehen unterschiedliche Adressen trotz?

Diese Frage kommt von C pass void pointer using shared memory.

Danke.

+1

ihre realen physikalischen Adressen werden – user2760375

+0

geteilt Wie Sie die Erklärung in der Antwort verstanden haben, nehmen Sie es bitte – tez

Antwort

14

Der gesamte Speicher, der aktiviert wird, ist physisch.

Die Prozesse können den physikalischen Speicher jedoch nicht direkt adressieren. Sie haben virtuelle Adressen, die der Kernel in physikalische Adressen auflöst. Wenn eine gemeinsam genutzte Speicherregion eingerichtet wird, wird derselbe physische Speicherort von den mehreren Prozessen adressiert. Die virtuellen Adressen können jedoch unterschiedlich sein. Jeder Prozess verwendet die virtuelle Adresse, die er nur in seinem eigenen Kontext erhalten hat. Beide virtuellen Adressen beziehen sich auf denselben physikalischen Speicher.


Um dies näher auszuführen, im Fall eines gemeinsam genutzten Speicherbereiches, die gleiche physikalische Speicheradresse adressierbar durch mehrere Prozesse gleichzeitig, da beide der Prozesse von virtuellen Adressen, die auf die gleiche physikalische Adresse verweisen.

Zum Beispiel ist folgendes zu beachten:

  • virtuelle Adresse V1 (in Prozess T1 Kontext)
  • virtuelle Adresse V2 (in Prozess T2 Kontext)

zeigen beide auf den gemeinsamen Speicherbereich.
Dies ist tatsächlich eine gemeinsame physikalische Adresse P.Jetzt

,
Prozess T1 virtuelle Referenzierung Adresse V1
OR
Prozess T2 Referenzierung virtuelle Adresse V2

in einem Zugriff auf physikalische Adresse führen P da der Kernel beide virtuellen Adressen auf die gleiche Phy überträgt Speicherort im Speicher.


beispielsweise in dem folgenden Diagramm die physikalische Speicher PFN4 wird durch Prozesse X und Y unter Verwendung des gemeinsam VPFN3 und VPFN1 in ihren jeweiligen Kontexten.

Virtual memory maps for 2 processes

+0

OK. Ich habs. Danke für die ausführliche Erklärung. Jetzt klar. Aber in dem von mir geteilten Link versuchte ich, eine Prozessadresse mit geteiltem Speicher zu teilen, und im zweiten Beispiel versuchte ich, die Adresse und den Wert an dieser Adresse zu lesen, aber ich kann nur Adresse oder Wert teilen, nicht beides. – skanzariya

+0

Eine virtuelle Adresse ist nur im Prozesskontext gültig. Sobald ein Kontextwechsel stattfindet und ein anderer Prozess ausgeführt wird, enthalten die geladenen neuen Seitentabellen möglicherweise keine physische Standortzuordnung für diese bestimmte Adresse, die einen Segfault verursacht. Selbst wenn zufällig ein physischer Speicherplatz tatsächlich auf die gleiche virtuelle Adresse in dem neuen Prozess abgebildet wird, ist es NICHT garantiert, auf den gleichen physikalischen Speicherort wie im ursprünglichen Prozess zu zeigen. Gehen Sie diese [** Antwort **] (http://stackoverflow.com/a/20348391/319204) durch, um das Problem, mit dem Sie konfrontiert sind, richtig zu verstehen. – TheCodeArtist

Verwandte Themen