El truco consiste simplemente en redefinir el operador “new” para la clase de los objetos que queremos compartir:
extern "C++" { using namespace std; namespace avelino { class TShared { private: int a; public: TShared(); void setA(int v); int getA(); static void *memArea; void *operator new (unsigned int size); }; } } ... void *TShared::operator new (unsigned int size) { return TShared::memArea; }
Como se puede observar, hacemos que
new TShared()
devuelva un puntero a un área de memoria controlada por nosotros (no estoy implementando el delete
ni estoy realizando una gestión de memoria como tal: obsérvese que dos new TShared()
seguidos devolverían la misma posición de memoria, estoy haciéndolo así para facilitar la comprensión).Bueno, ya tenemos una clase que, al hacerle
new
nos va a devolver un puntero a una dirección de memoria controlada por nosotros. Ahora sólo nos queda inicializar dicho puntero adecuadamente.Debe haber un proceso que cree el objeto en memoria compartida:
int shmid = shmget(SHM_KEY, sizeof(TShared), IPC_CREAT | IPC_EXCL | 0700); TShared::memArea = shmat(shmid, NULL, 0); TShared *p = new TShared(); p->setA(12345);
Como se puede ver, antes de hacer el
new TShared()
inicializo TShared::memArea
con la zona de memoria compartida que acabo de crear (he omitido, por claridad, los if
que controlan los posibles errores que puedan devolver la funciones shmget
, shmat
, etc.). Ahora nuestro objeto de tipo TShared
está en la memoria compartida identificada por SHM_KEY
(una constante cualquiera definida por nosotros y mayor que cero).Si otro proceso quiere acceder a dicho “objeto compartido” sólo tendrá que acceder a dicha memoria compartida y hacer el cast correspondiente:
int shmid = shmget(SHM_KEY, sizeof(TShared), 0700); TShared::memArea = shmat(shmid, NULL, 0); TShared *p = (TShared *) TShared::memArea; cout << "a = " << p->getA() << endl;
El código fuente completo lo he puesto en la sección soft de la web.
[ 2 comentarios ] ( 7474 visualizaciones ) | [ 0 trackbacks ] | enlace permanente | ( 3 / 1955 )