Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using shared memory with fork()

I already looked at the only similar post I could find, but it wasn't what I was looking for.

Basically, I'm trying to run the Odd-Even Sort with forking, so the child runs odds and parent runs the evens. These both require the sharing of the vector inputValues, as well as the boolean sorted.

The following code is without any of my failed attempts at sharing memory, and is just the basic framework for using forks with the search algorithm:

while(!sorted)
{
    pID = fork();
    sorted = true;
    cout << "Sort set to TRUE." << endl;

    if(pID == 0)
    {
        int num = 1;
        cout << "Child swap run" << endl;
        Swap((void *) num);
        cout << "Status: " << ((sorted) ? "SORTED" : "UNSORTED") << endl;
        exit(0);
    }
    else if(pID < 0)
    {
        cout << "Failed to fork." << endl;
        exit(1);
    }
    else
    {
        wpid = waitpid(pID, &status, waitStatus);
        int num = 0;
        cout << "Parent swap run" << endl;
        Swap((void *) num);
        cout << "Status: " << ((sorted) ? "SORTED" : "UNSORTED") << endl;
    }
}

I've tried multiple ways of hacking out this sharing of memory, but can't find any one resource that really explains HOW it works, what I need, and the best way to do it.

So, my requirements are as follows:

  • The parent and child must be able to share and manipulate a global vector and boolean
  • This must be able to run in a loop, as shown
  • This must work with the variables being used in main() and in the swap() function

If you have any tips, I'd greatly appreciate them. Thanks!

like image 394
Befall Avatar asked Jun 23 '11 04:06

Befall


1 Answers

You're going to have to use shmget() and shmat() to setup a shared memory object, but unfortunately that won't be a dynamic memory object like a std::vector. In other words, you'll have to declare the entire size of the object at the point of initialization of the shared memory object. The process though is pretty straight-forward, in that in your parent you'll call shmget() with the IPC_CREAT flag to create the shared memory object and get a ID value for the object. Then call shmat() with the ID value to get a pointer to the object. Next, initialize the object with default values. When you fork to your child process, the pointer returned from shmat() will still be valid in the child process, so you can then share memory in both the parent and child using the same pointer variable.

You'll also want to declare in the parent process before you fork any children a semaphore using sem_init() with the pshared attribute set to a value greater than 0. Then both the parent and child processes can use the semaphore to control access to the shared memory object.

Again though, keep in mind the shared memory object is not a dynamic object, so you'll need to allocate enough space for it when you initialize it.

like image 102
Jason Avatar answered Sep 26 '22 10:09

Jason