将对象放在共享内存中以便在 .so 之间使用



将对象放在共享内存中是我正在处理的项目中的一小部分共享对象(linux库)中对象重复使用对象的首选方法。我以前从未使用过共享记忆,所以我在这里有点盲目。UI/Execute-Bit-set应用程序实例化某些对象(首选项和杂项utils)然后加载libs并进行工作。杂物的util对象很小,数量不多。到目前为止,分配共享内存块和传输字符串已经成功。现在,我需要确保libs可以访问UI设置的util对象。

进行了几天的研究后,我想到了这个简单的模型。(我将示例类" pod"命名为" 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

我还没有在项目中实施此模型,仍在进行研究。但是,在使用共享内存中,该特定用途的信息很少。我希望一个知识渊博的人能简要批评这一代码,并告诉我缺少什么(如果有的话)。我认为我的主要问题是;我一遍又一遍地读到,在共享段上实例化类对象是有问题的,但我并没有觉得如此。

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

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

我已经看到人们在大多数情况下工作,但这很痛苦。使用索引代替指针可以有所帮助。

添加其他问题。您必须学会在过程之间使用静音/futexes,以避免种族条件。

最新更新