fork(),C 中的共享内存和指针

Posted

技术标签:

【中文标题】fork(),C 中的共享内存和指针【英文标题】:fork(), shared memory and pointers in C 【发布时间】:2019-10-30 21:48:32 【问题描述】:

我无法在具有共享内存的进程之间共享指向对象的指针。

我可以成功地在不同进程之间共享如下结构:

    // Data to be shared among processes
    struct Shared_data 
        int setPointCounter;
        struct Point old_point;
        pthread_mutex_t my_mutex;
     *shd;

该结构被声明为全局(假设它位于 main() 之前)。

我将共享内存初始化为main:

shd = (struct Shared_data *) (mmap(NULL, sizeof *shd, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0));

然后在某个时候我执行一个 fork()。它工作正常。

当我不得不分享这样的东西时,问题就出现了:

    // Data to be shared among processes
    struct Shared_data 
        int setPointCounter;
        struct Point old_point;
        MyObject *obj;
        pthread_mutex_t my_mutex;
     *shd;

我主要从第三方库调用一个函数,该函数返回一个指向 MyObject 类型对象的指针,我想以某种方式共享它。我该怎么做?

通过在网上搜索,我发现了一些与相对指针相关的东西,但我不确定它是否会起作用,同时我不知道如何正确地做到这一点。

我正在使用 Linux (Slackware 64 14.2),语言是 C/C++(实际上主要是 C)。

提前感谢您的宝贵时间。

【问题讨论】:

您需要将对象复制到共享内存中。指针指向非共享内存。 直接共享该对象的唯一方法是确保将其分配在共享的内存中。如果您无法更改库、为其提供存储空间或自己复制对象,则您只能进​​行诸如找出它使用的分配器并拦截之类的黑客攻击。 重点是我认为访问该对象的唯一方法是通过指针,因为我在 main() 中调用的函数属于另一个库并返回一个指针。 共享内存可以在不同的进程中挂载到不同的地址。您需要使用偏移量而不是指针值。 Boost 一个专门设计用于在共享内存中复制 STL 的库:进程间。寻找灵感。 我想我会改变方法来解决我的问题。谢谢大家的建议! 【参考方案1】:

基本上,指针是一个进程的虚拟空间中某些数据的地址。您不能在进程之间共享指针,因为这些指针将在不同的地址空间中解释(通常,这也适用于内核模式虚拟空间和相同进程的用户模式)。让我们举个例子……你做了一些分配(在它们之间你做了一个mmap(2)分配)然后你fork(2)另一个进程。在那之前,如果我们认为两个进程在分叉之前都存在,那么所有内存地址都指向相同的位置,它们会一直在做同样的事情,得到相同的结果,等等。

但是一旦两个进程彼此分离,在一个进程中进行的所有分配都可能与另一个进程中的相同分配不同,因为每个进程的不同历史可能会提供不同的结果从任何分配器。只需假设任务中的一些时间顺序和一些时间相关的状态变化......在此之后,两个进程的状态将不同。

现在假设您在一个进程中有一个指针,它指向您想要与另一个进程共享的数据结构。但是另一个进程甚至没有分配相同的东西......所以通过例如0x00456211ff 指向另一个进程将指向另一个进程中没有分配任何内容的位置(导致SIGSEGV 信号和进程中止)

一旦进程转移它们的虚拟空间存储不同的东西,一个空间中的虚拟指针在另一个进程中是不可解释的。

【讨论】:

非常感谢 Luis,超级详尽的解释! 不客气...如果您对答案感到满意,您应该选择您喜欢的答案。

以上是关于fork(),C 中的共享内存和指针的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C 中与 Linux 一起使用共享内存

如何在python和C / C ++中使用共享内存

如何在 fork() 创建的进程之间共享内存?

C: 多个分叉

fork后如何创建共享内存?

C ++释放共享库中动态分配的内存导致崩溃