문제

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.

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...)

#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.

도움이 되었습니까?

해결책

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.

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top