Ошибка при попытке присоединить используемый адрес разделяемой памяти - PullRequest
3 голосов
/ 03 ноября 2011

Получение сообщения «Неверный аргумент» при использовании shmget со вторым параметром, не равным NULL.

Он компилируется нормально, но при выполнении я получаю это сообщение об ошибке.

У меня естьзастрял в этом весь день.Надеюсь, вы можете помочь мне!:)

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


int main()
{
    int idSharedMem;
    int *varSharedMem1;
    int *varSharedMem2;

    /* Create the shared memory */
    idSharedMem = shmget((key_t) 0001, sizeof(int), IPC_CREAT | 0666);

    if (idSharedMem == -1)
    {
        perror("shmget");
    }

    /* Allocate a memory address and attached it to a variable */
    varSharedMem1 = shmat(idSharedMem, NULL, 0);

    if (varSharedMem1 == (int *) -1)
    {
        perror("shmat1");
    }

    /* Sign a value to the variable */
    *varSharedMem1 = 5;

    /* Attach an existing allocated memory to another variable */
    varSharedMem2 = shmat(idSharedMem, varSharedMem1, 0);

    if (varSharedMem2 == (int *) -1)
    {
        /* PRINTS "shmat2: Invalid argument" */
        perror("shmat2");
    }

    /* Wanted it to print 5 */
    printf("Recovered value %d\n", *varSharedMem2);

    return(0);
}

Ответы [ 2 ]

4 голосов
/ 03 ноября 2011

С помощью shmat(idSharedMem, varSharedMem1, 0); вы пытаетесь присоединить сегмент в местоположении varSharedMem1.Однако вы ранее прикрепили сегмент в этом месте, что приведет к EINVAL.Linux предоставляет флаг SHM_REMAP, который можно использовать для замены ранее отображенных сегментов.

man-страница shmat:

(для Linux) флаг SHM_REMAP может быть указан в shmflg, чтобы указать, что сопоставлениесегмента должен заменить любое существующее отображение в диапазоне, начиная с shmaddr и продолжая для размера сегмента.(Обычно ошибка EINVAL возникает, если сопоставление уже существует в этом диапазоне адресов.) В этом случае shmaddr не должен быть NULL.

1 голос
/ 03 ноября 2011

Из справочной страницы shmat:

If shmaddr isn't NULL and SHM_RND is specified in shmflg, the attach occurs at the
address equal to shmaddr rounded  down  to  the nearest multiple of SHMLBA. 
Otherwise shmaddr must be a page-aligned address at which the attach occurs.

больше из справочной страницы shmat:

Using shmat() with shmaddr equal to NULL is the preferred, portable way of 
attaching a shared memory segment.

Чтобы сделать второе присоединение, просто:

varSharedMem2 = shmat(idSharedMem, NULL, 0);
...