Thread: accessing shared memory via forked processes

  1. #1
    Registered User
    Join Date
    Jun 2010
    Posts
    7

    accessing shared memory via forked processes

    I have a test program here that conveys the troubles that I am having with a current project. The intent is to have one "creator" process running, which will set up a shared memory segment. The creator will the fork "node" processes which will modify the shared memory segment. This would be very easy if it were not for the fact that each forked process makes a call to execv in order to run the desired program. Here is what I've been trying to do, I have not gotten it to work so far.

    Code for the "creator" process:
    Code:
    #include <sys/stat.h>
    #include <sys/wait.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/mman.h>
    #include <string.h>
    int main (void){
      char *data;
      int shmfd=-1;
      pid_t pid;
      shmfd = shm_open("/SHAREDMEM",O_CREAT|O_RDWR,S_IRUSR|S_IWUSR);
      if(shmfd==-1){
        perror("creator:shm_open");
        exit(EXIT_FAILURE);
      }
      if(ftruncate(shmfd,1024)){
        perror("creator:ftruncate");
        exit(EXIT_FAILURE);
      }
      data = mmap(NULL,1024,PROT_READ|PROT_WRITE,
                          MAP_SHARED,shmfd,0);
    
      pid = fork();
      if(pid==0){
        execv("node1",NULL);
      }else{
        waitpid(pid,NULL,0);
      }
    
      pid = fork();
      if(pid==0){
        execv("node2",NULL);
      }else{
        waitpid(pid,NULL,0);
      }
    
    
      printf("data: %s\n",data);
    
      close(shmfd);
      munmap(data,1024);
      shm_unlink("/SHAREDMEM");
      return 0;
    }
    Code for "node" process: (node1 is almost exactly the same as node2)
    Code:
    #include <stdio.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/mman.h>
    #include <string.h>
    int main (void){
      char *data;
      int shmfd=-1;
    
      shmfd = shm_open("/SHAREDMEM",O_RDWR,0);
      if(shmfd==-1){
        perror("node1:shm_open");
        exit(EXIT_FAILURE);
      }
      data = mmap(NULL,1024,PROT_READ|PROT_WRITE,
    	      MAP_SHARED,shmfd,0);
      strcat(data,"Node_One");
      return 0;
    }
    This code compiles, but obviously doesn't work as intended. I commented out the calls to ftruncate and mmap within creator.c because they were causing a segfault.
    Any help would be greatly appreciated!

    Thank you
    Last edited by rklockow; 06-29-2010 at 12:42 PM. Reason: code was edited to reflect recent changes:

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Why hasn't the shm object been opened in r/w mode?
    And you wonder why it segfaults when it calls ftruncate()?
    Also remove ftruncate() from "node", leave that to the "creator".

  3. #3
    Registered User
    Join Date
    Jun 2010
    Posts
    7
    Okay, I think I understand the reason for ftruncate() a little better now. I have tried what you suggested however I'm still not seeing any changes in the shared memory segment. Any other suggestions?

  4. #4
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by rklockow View Post
    Okay, I think I understand the reason for ftruncate() a little better now. I have tried what you suggested however I'm still not seeing any changes in the shared memory segment. Any other suggestions?
    Can you post the updated code.

  5. #5
    Registered User MacNilly's Avatar
    Join Date
    Oct 2005
    Location
    CA, USA
    Posts
    466
    Code:
    pid = fork();
      if(pid==0){
        execv("node1",NULL);
      }else{
        waitpid(pid,NULL,0);
      }
    
      pid = fork();
      if(pid==0){
        execv("node2",NULL);
      }else{
        waitpid(pid,NULL,0);
      }
    The parent process forks a child then waits for that child to complete. Then forks another process and waits for THAT child to complete. How's this any different from sequential logic?

    If you want two processes running concurrently, you need something more like

    Code:
    int i;
    pid_t childIds[2];
    //pid_t id = -1;
    
    for (i = 0; i < 2; ++i) {
        pid_t id = fork();
        if (id == 0) break;
        childIds[i] = id;
    }
    
    if (id == 0)
      do_child_process();
    else {
      do_parent_process();
      for (i = 0; i < 2; ++i)
          waitpid(childId[i], NULL, 0);
    }
    Last edited by MacNilly; 06-29-2010 at 04:44 PM.

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    All of the shm_XXX() stuff is completely superfluous. Just create a file on the filesystem of sufficient size, open() it, then mmap() it in the different processes.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  7. #7
    Registered User
    Join Date
    Jun 2010
    Posts
    7
    @Macnilly,
    That is just one of the restraints of the project that I'm working on. I need one process running in the background while it forks and then runs the executables indicated in the command tail. The reason that I'm forking and not just doing sequential logic is that the call to execv() is necessary.

    @itCbitC
    I edited my first post yesterday to reflect the changes that I made. I will post a newly revised edition shortly, as I am just getting to work on it now.

    My goal with this test program is to see the changes made by node1 and node2 when the creator reaches the printf at the end of its main.

    Thank you all for the responses


    -edit: Problem solved!
    My error was that I was calling ftruncate each time I opened the shared memory segment (along with memsetting the shared character buffer). This caused the buffer to be empty every time I tried to access the data.
    Thanks for the help!
    Last edited by rklockow; 06-30-2010 at 06:45 AM.

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    I still don't understand why you're bothering with IPC shm. You seem to want to manipulate the shared region in a file-like manner. In that case, why not actually use a file and mmap it directly?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with insert/delete binary search tree
    By Nazgulled in forum C Programming
    Replies: 39
    Last Post: 03-25-2009, 04:24 PM
  2. Problems with shared memory shmdt() shmctl()
    By Jcarroll in forum C Programming
    Replies: 1
    Last Post: 03-17-2009, 10:48 PM
  3. BSD mmap for shared memory - am I right?
    By sean in forum Linux Programming
    Replies: 21
    Last Post: 03-09-2009, 01:57 PM
  4. shared memory not getting freed
    By Elkvis in forum Linux Programming
    Replies: 19
    Last Post: 02-29-2008, 04:48 PM
  5. shared libraries, datasegment and multiple processes
    By ashim_k1 in forum Linux Programming
    Replies: 1
    Last Post: 02-28-2008, 02:23 PM