Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared Memory With Two Processes In C?

I want to do the following:

Parent process creates a child process. Then the child process reads n int's from the user and store them in a shared memory. The parent process then displays them.

I reached the following:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#define SHMSIZE 27
int main() {
   int shmid;
   int *shm;
   int *n;

   if(fork() == 0) {
      shmid = shmget(2009, SHMSIZE, 0);
      shm = shmat(shmid, 0, 0);
      n = shm;
      int i;
      for(i=0; i<5; i++) {
         printf("Enter number<%i>: ", i);
         scanf("%d", n++);
      }
      printf ("Child wrote <%d>\n",shm);
      shmdt(shm);
   }
   else {
      wait();
      int *s;
      shmid = shmget(2009, SHMSIZE, 0666 | IPC_CREAT);
      shm = shmat(shmid, 0, 0);
      s = shm;
      wait(NULL);
      printf ("Parent reads <%d>\n",shm) ;
      shmdt(shm);
      shmctl(shmid, IPC_RMID, NULL);
   }
   return 0;
}

And the output is just this line:

Enter number<1>:

And if I entered a number, let's say 25, it outputs this:

Parent reads <r>

r: random -ve number changes every time I execute the code

It never went through the child process code ! Am I doing this in a wrong way ?

like image 476
iTurki Avatar asked Nov 18 '11 18:11

iTurki


People also ask

Can two process shared memory?

Yes, two processes can both attach to a shared memory segment. A shared memory segment wouldn't be much use if that were not true, as that is the basic idea behind a shared memory segment - that's why it's one of several forms of IPC (inter-Process communication).

How do I share data between two processes?

One common way is to use files to communicate between the processed. Each can write to a specific file that the other reads from. You can use WCF, the registry, network interface, message queues or any other mechanism that lives outside the process. The registry as an IPC mechanism.

Do parent and child processes share memory?

Answer: Only the shared memory segments are shared between the parent process and the newly forked child process. Copies of the stack and the heap are made for the newly created process.

Do processes share the same memory?

Processes don't share memory with other processes. Threads share memory with other threads of the same process.


1 Answers

Ok, better collect in an answer instead...

There are several problems with you program. If you enable warnings when building (I use -Wall -Wextra) a lot of them will be quite evident.

The first two problems I already mentioned in my comments, but I explain them here:

  1. The first is the call to wait(). There is no wait function in C or POSIX that takes no argument.
  2. The second problem is the scanf call, you are calling it with *++, where *n takes the value of the memory pointed to by n which most likely can result in a crash. Remove the asterisk.
  3. The third problem is that you treat the shared memory as both an array of integers (with n) and as a string. You cant really do both, pick one or the other.
  4. You create the shared memory in the parent process, but wait for the child process to finish before you create the memory.
  5. There is a race condition between the parent and child process, since the share memory might be created after the child tries to access it.

Edit I came up with this instead, which seems to work for me. I added comments on the things I changed.

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/wait.h>  /* Needed for the wait function */
#include <unistd.h>    /* needed for the fork function */
#include <string.h>    /* needed for the strcat function */
#define SHMSIZE 27
int main() {
   int shmid;
   char *shm;

   if(fork() == 0) {
      shmid = shmget(2009, SHMSIZE, 0);
      shm = shmat(shmid, 0, 0);
      char *s = (char *) shm;
      *s = '\0';  /* Set first location to string terminator, for later append */
      int i;
      for(i=0; i<5; i++) {
         int n;  /* Variable to get the number into */
         printf("Enter number<%i>: ", i);
         scanf("%d", &n);
         sprintf(s, "%s%d", s, n);  /* Append number to string */
      }
      strcat(s, "\n");  /* Append newline */
      printf ("Child wrote <%s>\n",shm);
      shmdt(shm);
   }
   else {
      /* Variable s removed, it wasn't used */
      /* Removed first call to wait as it held up parent process */
      shmid = shmget(2009, SHMSIZE, 0666 | IPC_CREAT);
      shm = shmat(shmid, 0, 0);
      wait(NULL);
      printf ("Parent reads <%s>\n",shm) ;
      shmdt(shm);
      shmctl(shmid, IPC_RMID, NULL);
   }
   return 0;
}

Do note that point 5 in the list above have not been resolved.

like image 71
Some programmer dude Avatar answered Oct 06 '22 01:10

Some programmer dude