How to instantiate objects in shared memory?

Asked

Viewed 59 times

3

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

Note: I don’t know if it makes a difference, but the Barrier is an object Static in the parent class.

#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);
}

2 answers

4

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

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

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

I suggest the implementation of a daughter class of Barrier calling for BarrierSharedMemory, which is the specialisation of a Barrier using the shared memory.

This daughter class will be responsible for encapsulating calls from shmat() and shmget(), look at the 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 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);

}
  • I tested the solution and unfortunately it didn’t work. When I place a printf within the Wait() function the value of the barrier counter remains unchanged in both processes, indicating that there was no sharing. Normal barrier with other parallelization methods works correctly, prints show values being lowered.

0


I found the error. The shmget itself already "creates" an object in the shared memory. Correcting the attribution error I made earlier, just make a function that initializes this object, as if it were a set in the properties, since the 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);
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.