How to instantiate objects in shared memory?

2

I have an application in which there are several modes of parallelization. However, when I am going to parallelize through fork () the barrier is not shared between the processes, is there any difference of Shm in dealing with instantiation via new or is there another way to provide the sharing of this barrier?

#include "ProcessMode.hpp"

ProcessMode::ProcessMode(IndexGenerator *index_generator_template, numerical *numerical_array, short number_of_processors)
    : ParalelizationMode(index_generator_template, numerical_array, number_of_processors) {

    // Sharing the barrier for use among the processes
    int ptr_id = shmget(IPC_PRIVATE, sizeof(Barrier), IPC_CREAT | 0666);
    ParalelizationMode::barrier = (Barrier*) shmat(ptr_id, NULL, 0);
    ParalelizationMode::barrier = new Barrier(number_of_processors);
}

void ProcessMode::run() {
    pid_t pid;
    int id = 0;

    // Create processes
    for (short i = 1; i < number_of_processors; i++) {
        pid = fork();

        if(pid > 0) {
        continue;
        }
        else {
            id = i;
            break;
        }
    }

    calculate(new Calculator(numerical_array, index_generator_template->clone(id)));
    ParalelizationMode::barrier->wait();

    if (pid == 0) exit(0);
}
    
asked by anonymous 20.11.2018 / 13:33

2 answers

0

I found the error. Shmget by itself already "creates" an object in shared memory. Fixing the attribution error I've previously committed, just do a function that initializes this object, as if it were a set in the properties, since shmget does not receive any parameters to "instantiate the object". Solution:

ProcessMode::ProcessMode(IndexGenerator *index_generator_template, numerical *numerical_array, short number_of_processors)
    : ParalelizationMode(index_generator_template, numerical_array, number_of_processors) {

    int id = shmget(IPC_PRIVATE, sizeof(Barrier), IPC_CREAT | 0666);
    ParalelizationMode::barrier = (Barrier*) shmat(id, NULL, 0);
    barrier->initSharedBarrier(number_of_processors);
}
    
22.11.2018 / 23:13
3

Note that the static attribute of parent class ParalelizationMode::barrier is being overwritten immediately after the shmat() call:

...
ParalelizationMode::barrier = (Barrier*) shmat(ptr_id, NULL, 0);
ParalelizationMode::barrier = new Barrier(number_of_processors);
...

When doing this, the void * pointer that was returned by shmat() is lost, causing the function call to have no effect!

I suggest the implementation of a child class of Barrier called BarrierSharedMemory , which is the specialization of a barrier using shared memory.

This child class will be responsible for encapsulating calls of shmat() and shmget() , see example:

class BarrierSharedMemory : public Barrier {
     public:
         BarrierSharedMemory( int );
         virtual ~BarrierSharedMemory( void );
     private:
         int m_id;
         void * m_ptr_shm;
};

// ...

BarrierSharedMemory::BarrierSharedMemory( int n )
      : Barrier( n )
{
    this->m_id = shmget(IPC_PRIVATE, sizeof(Barrier), IPC_CREAT | 0666);
    this->m_ptr_shm = shmat(this->m_id, NULL, 0);
}

Making it possible to rewrite the ProcessMode constructor as follows:

ProcessMode::ProcessMode(IndexGenerator *index_generator_template, numerical *numerical_array, short number_of_processors)
    : ParalelizationMode(index_generator_template, numerical_array, number_of_processors) {

    ParalelizationMode::barrier = new BarrierSharedMemory(number_of_processors);

}
    
20.11.2018 / 15:18