shmat () возвращает другой "shmaddr" для того же самого "shmkey" - PullRequest
3 голосов
/ 08 декабря 2011

Вот мои настройки ...

/* Bounded Buffer item structure */
struct item {
    int  id;  /* string index value */
    char str[80];  /* string value */
};

/* Structure for the shared memory region */
typedef struct {
    int    debug;           /* debug flag */
    int    in;              /* index of next empty slot */    
    int    out;             /* index of next full slot  */
    char   MUTEXname[32];   /* name of the MUTEX semaphore */
    char   EMPTYname[32];   /* name of the EMPTY semaphore */
    char   FULLname[32];    /* name of the FULL semaphore  */
    struct item buff[BUFFSIZE];  /* circular buffer for producer/consumer items*/
    char   strarray[MAX_STRINGS][80]; /* shared array of strings for consumers */
} shr_mem_t;

/* Values for obtaining a shmid key via ftok() */
#define KEYPATH "."
#define KEYPROJ 4520

Main: (будет выполнять fork () процессы "Producer" и "Consumer")

/* Use ftok() to get a value for a key to identify a shared memory segment */
shm_key = ftok(KEYPATH, KEYPROJ);

/* Create the shared memory segment */
shmid = shmget(shm_key, sizeof(shr_mem_t), IPC_CREAT | IPC_EXCL | 0660);

/* Attach shared memory segment to the parent process */
shmptr = shmat(shmid, NULL, 0);

Производитель:

/* Use ftok() to get value for the key to identify the shared memory segment */
shm_key = ftok(KEYPATH, KEYPROJ);

/* Get the ID of the existing shared memory segment */
shmid = shmget(shm_key, sizeof(shr_mem_t), 0660);

/* Attach the shared memory segment */
shmptr = shmat(shmid, NULL, 0);

Потребитель:

/* Use ftok() to get value for the key to identify the shared memory segment */
shm_key = ftok(KEYPATH, KEYPROJ);

/* Get the ID of the existing shared memory segment */
shmid = shmget(shm_key, sizeof(shr_mem_t), 0660);   

/* Attach the shared memory segment */
shmptr = shmat(shmid, NULL, 0);

Ошибка тестирования: (ради краткости ...)

if (shmid == -1) {
    perror("shmget failed in __________");
    exit(1);
} else {
    sprintf(errString, "<*> __________ shared memory id: %i ", shmid);
    perror(errString);
}

if(shmptr == (void *)(-1)) {
    perror("shmat failed in __________");
    exit(1);
} else {
    sprintf(errString, "<*> __________ attaching to shared memory address: %p ", shmptr);
    perror(errString);
}

Выход:

<*> Main creating shared memory id: 101376 : No such file or directory
<*> Main attaching to shared memory address: 16000 : No such file or directory
Creating the producer and consumer processes...
<*> Producer located shared memory id: 101376 : Successful
<*> Consumer located shared memory id: 101376 : Successful
<*> Producer attaching to shared memory address: 10000 : Successful
<*> Consumer attaching to shared memory address: 10000 : Successful

Что происходит с адресом общей памяти? Как процессы Main и Prod / Cons получают разные shmaddr, когда они присоединяются, когда у них одинаковые shmid?

Заранее спасибо,

Z @ K!

Ответы [ 3 ]

5 голосов
/ 08 декабря 2011

Существует два набора адресов. «Адреса микросхем ОЗУ», то есть аппаратные, физические, реальные или супервизорные адреса, начинаются с вашей первой микросхемы ОЗУ с 0 и перемещаются вверх. Однако во всех «настоящих многозадачных» операционных системах каждый процесс получает собственную «виртуальную память». ЦП и ОС взаимодействуют, создавая у каждого «иллюзии» то, что он один на своем компьютере, со своим собственным адресным пространством, с таблицей (в ядре и ЦП, в зависимости от архитектуры), отображаемой из «виртуального» (согласно -процесс) адреса к адресам "реальный / аппаратный / супервизор".

Общая память - это особый случай, когда одна и та же «реальная память» адресована из более чем одного процесса. Виртуальные адреса, которые возвращает shmat, являются локальными для каждого вызывающего абонента.

Аналогично, когда вы загружаете библиотеку общего объекта (.so), она может отображаться в отдельное адресное пространство в каждом процессе.

3 голосов
/ 08 декабря 2011

Совершенно законно, что один и тот же сегмент совместно используемой памяти отображается на разные виртуальные адреса в разных процессах.

2 голосов
/ 12 июля 2012

когда процесс вызывает shmat (), он возвращает виртуальный адрес разделяемой памяти. виртуальный адрес - это область памяти, видимая текущим процессом. другой процесс может отобразить общую память на другой виртуальный адрес в адресном пространстве процесса и, следовательно, разные возвращаемые значения вызова shmat () для разных процессов.

хорошее графическое описание того, что я только что сказал выше. http://poshmodule.sourceforge.net/posh/html/node3.html

...