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

时间:2022-07-21 13:24:15

Placing objects in shared memory is a preferred method for object re-use among a small collection of shared object (Linux libraries) in a project I am working on. I've never used shared memory before, so I'm a bit blind here. The ui/execute-bit-set app instantiates some objects (preferences and miscellaneous utils) then loads the libs and goes to work. The sundry util objects are small and not many in number. So far allocating a shared memory block and transferring strings has been successful. I now need to make sure the libs get access to the util objects set up by the ui.

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

After doing a few days of research I came up with this simple model. (I named the example class "POD" although it is a proper class. Please ignore that...)

经过几天的研究,我想出了这个简单的模型。 (我将示例类命名为“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);
}

Amazingly to me it worked right out of the gate:

令我惊讶的是它在门外工作:

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

I haven't implemented this model in my project yet, still doing research. But the info out there in using shared memory for this specific use is pretty sparse. I'm hoping a knowledgeable person will critique this code briefly and tell me what's missing, if anything. I think my main question is; over and over I read that instantiating class objects on shared segments was problematic, and I didn't find it to be so.

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

1 个解决方案

#1


1  

There are several hard parts to putting objects in shared memory. They all have to do with pointers. You can't use any pointers, even within the shared memory segment, because it may be loaded in different spots in different processes. You have to be very sure that the objects contained don't malloc any space, since that space will be on the heap and not in shared memory, and the bad pointer can do bad things to other procs. They can't have virtual functions, because the virtual function tables may be in different spots in the local process memory.

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

For example, putting a string in the object is bad, because that allocates memory for the string.

例如,在对象中放入一个字符串是不好的,因为它为字符串分配内存。

I've seen people work around most of these, but it is painful. Using indexes instead of pointers can help.

我见过人们围绕其中大部分工作,但这很痛苦。使用索引而不是指针可以提供帮助。

Add to this the other problems. You'll have to learn to use mutexes/futexes between process to avoid race conditions.

除此之外还有其他问题。您必须学会在进程之间使用互斥锁/ futex,以避免竞争条件。

#1


1  

There are several hard parts to putting objects in shared memory. They all have to do with pointers. You can't use any pointers, even within the shared memory segment, because it may be loaded in different spots in different processes. You have to be very sure that the objects contained don't malloc any space, since that space will be on the heap and not in shared memory, and the bad pointer can do bad things to other procs. They can't have virtual functions, because the virtual function tables may be in different spots in the local process memory.

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

For example, putting a string in the object is bad, because that allocates memory for the string.

例如,在对象中放入一个字符串是不好的,因为它为字符串分配内存。

I've seen people work around most of these, but it is painful. Using indexes instead of pointers can help.

我见过人们围绕其中大部分工作,但这很痛苦。使用索引而不是指针可以提供帮助。

Add to this the other problems. You'll have to learn to use mutexes/futexes between process to avoid race conditions.

除此之外还有其他问题。您必须学会在进程之间使用互斥锁/ futex,以避免竞争条件。