子进程更新共享 mmap 内存但父进程没有变化
Posted
技术标签:
【中文标题】子进程更新共享 mmap 内存但父进程没有变化【英文标题】:Child process updates shared mmap memory but no change in parent process 【发布时间】:2020-06-03 13:49:17 【问题描述】:我正在尝试将结构保存在由 mmap 创建的共享内存中,如下面的代码所示:
问题是,子进程似乎正在更新共享内存中的结构,但是当父进程尝试读取它时,它会引发错误。
struct name
char * name;
;
int main(int argc, char ** argv)
struct name * s_memory = mmap(NULL, sizeof(struct name), PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
pid_t p = fork();
if(p == 0)
printf("In Child Process\n");
s_memory->name = strdup("test name");
printf("Child Process name: %s \n", s_memory->name); // Print - test name ok!!
puts("exit child process");
exit(1);
else
sleep(1);
printf("Parent Process name: %s \n", s_memory->name); // SEGV !! - Not Updated
exit(0);
-
这里有什么问题?
为什么删除 strdup
并做这样的事情有效:
s_memory->name = "test name" // with strdup throws SEGV but works without strdup. why?
谢谢
【问题讨论】:
【参考方案1】:发生这种情况是因为您仅将 指针 存储到共享内存中的字符串,字符串本身由strdup
通过malloc
分配,它位于程序堆中,即在共享内存之外内存区域。
您应该将字符串本身存储在共享内存中,例如:
struct name
char name[1024];
;
// . . .
strncpy(s_memory.name, "test name", sizeof(s_memory.name));
【讨论】:
如果我想在原始struct name
中存储另一个 struct name
怎么办。这将如何运作?
@lynxx 你可以存储你想要的东西,但是指向进程内存的指针对其他进程不可用。好吧,您可以读取指针的值(位于共享内存中),但不能取消引用它。
@TedLyngmo 对不起,我想清楚。我希望多个进程共享动态数据,例如结构。那么,如果不能存储指针,如何将动态数据存储在共享内存中呢?
您需要分配足够的空间并可能创建自定义分配器/删除器。还要确保锁定您正在读取/写入的区域。您确定不想改用线程吗?
共享内存作为连续的内存块提供给您。您可以在其中存储任何复杂的结构。但是你需要自己管理它。例如,一开始您可以存储一个int size
,然后是struct name
的多个实例。当然你还需要一个互斥量或者信号量来同步更新,sleep
是不够的。还可以尝试谷歌搜索“C++ 中的共享内存管理器”。以上是关于子进程更新共享 mmap 内存但父进程没有变化的主要内容,如果未能解决你的问题,请参考以下文章