【问题标题】:Child process updates shared mmap memory but no change in parent process子进程更新共享 mmap 内存但父进程没有变化
【发布时间】: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);
}
  1. 这里有什么问题?
  2. 为什么删除 strdup 并做这样的事情有效:

         s_memory->name = "test name" // with strdup throws SEGV but works without strdup. why?
    

谢谢

【问题讨论】:

    标签: c++ c ipc shared-memory mmap


    【解决方案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++ 中的共享内存管理器”。
    猜你喜欢
    • 2012-07-29
    • 1970-01-01
    • 2016-06-25
    • 2011-06-26
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多