Динамическая общая память 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 процесса взаимодействовали или разделяли память, вам придется это сделать. Проверьте этот вопрос.
Другое решение - использовать потоки, которые совместно используют код и память.