Динамическая общая память linux в разных программах

Я создаю общую память в программе A со следующими кодами:

shm = shm_open("/mfs_hash_pool_container", O_CREAT|O_RDWR, 0666);

size = sizeof(struct mfs_hash_pool_container);

ftruncate(shm, size);

mfs_hash_pool_stat_p = (struct mfs_hash_pool_container *)mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, shm, 0);

Я использую это для хранения хэш-таблицы.

Другая программа B получит отправку addr (mfs_hash_pool_stat_p+offset) из программы A, но я не могу записать ее в B. Означает ли это, что я также должен открыть эту общую память в B? Есть ли другой способ решить это? Потому что я создаю эту память автоматически.

Спасибо, ребята.

4 ответа

Вы не можете просто использовать этот адрес в другой программе. Б должен:

  • Получите дескриптор файла: shm_open("/mfs_hash_pool_container", O_RDWR, 0)
  • Память карты для файлового дескриптора: mmap так же, как делает

Заметки:

  • Вам нужно проверить возвращаемое значение mmap (это может вернуться MAP_FAILED)
  • Вам не нужно приводить возвращаемое значение mmap

Отдельные процессы не разделяют память, поэтому адрес, передаваемый B из A, не будет указывать на сегмент совместно используемой памяти. Каждый процесс должен вызывать shm_open() и mmap() сегмент по отдельности.

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

Я не уверен в том, как связаны ваша программа A и программа B, но если вам удастся создать "B" из "A", используя fork() + execve() комбинации, то вам не нужно беспокоиться о передаче указателя памяти, так как оба процесса будут иметь одинаковую копию.

Для справки я привожу хороший пример кода, представленный на сайте IBM DeveloperWorks-

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/mman.h>
#include <sys/wait.h>

void error_and_die(const char *msg)
{
    perror(msg);
    exit(EXIT_FAILURE);
}

int main(int argc, char *argv[])
{
    int r;

    const char *memname = "sample";
    const size_t region_size = sysconf(_SC_PAGE_SIZE);

    int fd = shm_open(memname, O_CREAT | O_TRUNC | O_RDWR, 0666);
    if (fd == -1)
        error_and_die("shm_open");

    r = ftruncate(fd, region_size);
    if (r != 0)
        error_and_die("ftruncate");

    void *ptr = mmap(0, region_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (ptr == MAP_FAILED)
        error_and_die("mmap");
    close(fd);

    pid_t pid = fork();

    if (pid == 0)
    {
        u_long *d = (u_long *)ptr;
        *d = 0xdbeebee;
        exit(0);
    }
    else
    {
        int status;
        waitpid(pid, &status, 0);
        printf("child wrote %#lx\n", *(u_long *)ptr);
    }

    r = munmap(ptr, region_size);
    if (r != 0)
        error_and_die("munmap");

    r = shm_unlink(memname);
    if (r != 0)
        error_and_die("shm_unlink");

    return 0;
}

Прочитайте полную статью в ссылке выше, чтобы лучше понять общую память!

Процесс не делит память по умолчанию. Если вы хотите, чтобы эти 2 процесса взаимодействовали или разделяли память, вам придется это сделать. Проверьте этот вопрос.

Другое решение - использовать потоки, которые совместно используют код и память.

Другие вопросы по тегам