Linux C: доступ к общей памяти завершается неудачно с помощью `Invalid Argument`, даже если он был только что создан - PullRequest
2 голосов
/ 03 марта 2020

Эта моя функция отвечает за создание сегмента общей памяти. Как видите, я проверяю EEXIST на случай, если с этим ключом уже есть общая память. Поскольку я регулярно выполняю программу с тем же ключом, эта общая память существует после первого выполнения программы.

В качестве теста я пытаюсь получить доступ к общей памяти непосредственно после этого через shmat(). Но по какой-то причине это не удается. Это вывод консоли:

Shared memory with Key 4661 already exists, continue...
Failed to obtain `Shared Memory`: Invalid argument

Это функция:

#define SHM_KEY 0x1235
int create_shrd_memory(uint64_t size) {
    const int shmid = shmget(SHM_KEY, size, IPC_CREAT | IPC_EXCL);
    if(shmid == -1) {
        if(errno == EEXIST) {
            printf("Shared memory with Key %d already exists, continue...\n", SHM_KEY);
            char *shdmem = shmat(SHM_KEY, NULL, 0);
            if(shdmem == -1) {
                fprintf(stderr, "Failed to obtain `Shared Memory`: %s\n", strerror(errno));
            }
            shmdt(shdmem);
            return SHM_KEY;
        } else {
            fprintf(stderr, "Failed to obtain Shared Memory: %s\n", strerror(errno));
            perror("shmget");
            exit(1);
        }
    }

    return shmid;
}

Знаете ли вы, что происходит, если я однажды забыл позвонить shmdt()? Может ли это привести к этой ошибке?

1 Ответ

2 голосов
/ 03 марта 2020

shmat первый аргумент - это возвращаемое значение shmget, вы смешиваете ключ и идентификатор.

Ваш код должен выглядеть примерно так:

int create_shrd_memory(uint64_t size) {
    int shmid = shmget(SHM_KEY, size, IPC_CREAT | IPC_EXCL);
    if(shmid == -1) {
        if(errno == EEXIST) {
            printf("Shared memory with Key %d already exists, continue...\n", SHM_KEY);

            shmid = shmget(SHM_KEY, size, 0);

            char *shdmem = shmat(shmid, NULL, 0);
            if(shdmem == -1) {
                fprintf(stderr, "Failed to obtain `Shared Memory`: %s\n", strerror(errno));
            }
            shmdt(shdmem);
            return SHM_KEY;
        } else {
            fprintf(stderr, "Failed to obtain Shared Memory: %s\n", strerror(errno));
            perror("shmget");
            exit(1);
        }
    }

    return shmid;
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...