Linux C: время от времени не удается получить доступ к общей памяти - PullRequest
1 голос
/ 03 марта 2020

Я уже начал топи c об этом сегодня: Linux C: доступ к общей памяти не удается с помощью `Invalid Argument`, даже если он только что был создан

Но к сожалению, ответ на этот вопрос не решил мою проблему полностью.

Я все еще работаю с этой функцией:

#define SHM_KEY 0x1237
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, try to access it...\n", SHM_KEY);


            while((shmid = shmget(SHM_KEY, size, 0)) < 0) {
                fprintf(stderr, "Error access shared mem: %s\n", strerror(errno));
            }

            char *shdmem = shmat(shmid, NULL, 0);
            if(shdmem == -1) {
                fprintf(stderr, "Failed to obtain `Shared Memory` with id %d: %s\n", shmid, strerror(errno));
                return 0;
            }

            printf("Successfully accessed shared memory with id: %d!\n", shmid);
            shmdt(shdmem);
        } else {
            fprintf(stderr, "Failed to obtain Shared Memory: %s\n", strerror(errno));
            perror("shmget");
            exit(1);
        }
    }

    return shmid;
}

Три разных процесса обращаются к общей памяти (но каждый из них пишет в другую позицию). Основной процесс (который также запускает подпроцессы через fork()) читает статистику из общей памяти и печатает ее каждые 2 с:

void print_statistics(const int amnt_of_processes, int shmid) {

    uint8_t *shmd = shmat(shmid, NULL, 0);
    if(shmd == -1) {
        fprintf(stderr, "Failed to obtain `Shared Memory` with id: %d during statistics: %s\n", shmid, strerror(errno));
        return;
    }

    printf("STATISTICS:\n");

    for(uint8_t i = 0; i < amnt_of_processes; i++) {
        printf("\tPROCESS %d\n", i);

        struct stats_record *stats = (struct stats_record*)(shmd + sizeof(struct stats_record) * i);

        printf("\t->REC PACKETS: %lu\n", stats->rx_packets);
        printf("\t->LOST PACKETS: %lu\n", stats->rtp_nmbr_drpd_pckts);
        printf("\t->Gbit/s: %0.2f\n", (stats->bps / 1024.0));
    }
}

Вся операция работает нормально, но после трех или четырех запусков моего «программа распространения», доступ к разделяемой памяти больше невозможен (while-l oop никогда не возвращается, что означает, что shmget всегда возвращает ошибку: Error access shared mem: Invalid argument.)

Если я изменяю SHM_KEY с другим значением, скомпилируйте и запустите - все снова работает нормально (для трех или четырех выполнений программы). Кстати, никаких проблем во время выполнения!

Я отменяю выполнение программы на CTRL + C. Я думаю об этом из-за внезапного прерывания, подпроцессы не всегда могут вызвать shmdt(). Может ли это вызвать упомянутые проблемы?

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