【问题标题】:Putting objects in shared memory for use among .so's将对象放入共享内存中以供 .so 使用
【发布时间】:2014-03-07 21:52:23
【问题描述】:

将对象放置在共享内存中是在我正在处理的项目中的一小部分共享对象(Linux 库)中重用对象的首选方法。我以前从未使用过共享内存,所以在这里我有点盲目。 ui/execute-bit-set 应用程序实例化一些对象(首选项和其他实用程序),然后加载库并开始工作。各种 util 对象很小,数量也不多。到目前为止,分配一个共享内存块并传输字符串已经成功。我现在需要确保这些库可以访问由 ui 设置的 util 对象。

经过几天的研究,我想出了这个简单的模型。 (我将示例类命名为“POD”,尽管它是一个正确的类。请忽略它...)

#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <cstdlib>

using namespace std;

class PODject
{
public:
PODject() { cout << "Init POD" << endl; }
~PODject() { cout << "Destroy POD" << endl; }
string WhoAmI(void) { return "I am the POD"; }
};

int
main(int argc, char** argv)
{
    PODject* pBuf = NULL;
    void *shared_memory = (void*)0;
    int shmid;
    key_t mykey = 73867;

    shmid = shmget((key_t)mykey, sizeof(PODject), 0666 | IPC_CREAT);

    if (shmid == -1) {
        cerr << "shmget failed" << endl;
        return(1);
    }

    shared_memory = shmat(shmid, (void *)0, 0);
    if (shared_memory == (void *)-1) {
        cerr << "shmat failed" << endl;
        return(1);
    }

    pBuf = new (shared_memory) PODject;
    if(pBuf) {
        cout << "before" << endl;
        cout << pBuf->WhoAmI() << endl;
        cout << "after" << endl;
                pBuf->~PODject();
    }
    else
        cout << "No object" << endl;

    if (shmdt(shared_memory) == -1) {
        cerr << "shmdt failed" << endl;
        return(1);
    }

    if (shmctl(shmid, IPC_RMID, 0) == -1) {
        cerr << "shmctl(IPC_RMID) failed" << endl;
        return(1);
    }

    return(0);
}

令我惊讶的是,它一开始就奏效了:

$ ./a.out
Init POD
I am the POD
Destroy POD

我还没有在我的项目中实现这个模型,还在做研究。但是,将共享内存用于此特定用途的信息非常稀少。我希望有见识的人能简要地批评这段代码,并告诉我缺少什么,如果有的话。我认为我的主要问题是;我一遍又一遍地读到在共享段上实例化类对象是有问题的,但我发现不是这样。

【问题讨论】:

  • 我在这里看不到任何特定于 C++11 的内容。你能启发我吗?
  • 主啊,向技术人员提问就像放牧猫一样。请忽略该评论,无需启发。我什至把它编辑了。看到了吗?
  • 在您的问题中,您询问有关在 so (库)之间共享对象的问题。你不是说在进程之间共享对象吗?您不需要任何这些来在同一进程中的库之间共享对象
  • 还有一个。无论我重新编辑故事多少次,像你这样的人都会发现一些缺陷。我已经为像你这样的人编辑了我的问题。如果您不打算提供帮助,请不要发表评论。
  • @interval,您的问题仍被标记为 C++11。

标签: c++ linux ipc shared-memory


【解决方案1】:

将对象放入共享内存有几个困难的部分。它们都与指针有关。您不能使用任何指针,即使在共享内存段中也是如此,因为它可能会加载到不同进程的不同位置。您必须非常确定包含的对象不会分配任何空间,因为该空间将在堆上而不是在共享内存中,并且错误的指针会对其他过程造成不良影响。它们不能有虚函数,因为虚函数表可能位于本地进程内存中的不同位置。

例如,将字符串放入对象中是不好的,因为这会为字符串分配内存。

我见过人们解决其中的大部分问题,但这很痛苦。使用索引而不是指针会有所帮助。

加上其他问题。您必须学习在进程之间使用互斥体/futexes 以避免竞争条件。

【讨论】:

  • 我在我的字符串示例中使用了信号量,它似乎运行良好。我添加的对象示例很简单,但我希望使用常量/不可变数据,它会起作用。
  • 是的,如果您有简单的不可变数据,那么它应该可以正常工作。我没有看到任何信号量,但实际上对象中根本没有数据,只有几个方法。
  • 哦,我突然想到,在尝试使用 shmget 之前,您应该有代码来检查共享内存的存在。如果它已经存在,并且你有不变的数据,那么你应该只附加而不是初始化对象。
猜你喜欢
  • 2011-09-10
  • 1970-01-01
  • 2016-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多