I'm trying to have two child processes write two random integers to a shared memory, then have the parent read them. I cant seem to validate the writing as I get a segmentation fault whenever I try to access an array element in the parent process.
Trying to read from memory in child process right after writing does nothing.
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <time.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(){
srand(time(NULL));
int pid2;
key_t key = 12345;
int shmid = shmget(key, 2 * sizeof(int), IPC_CREAT|IPC_EXCL|0666);
int *array = (int *)shmat(shmid, 0, 0);
int pid1 = fork();
//write first array element
if (pid1 == 0){
int n1 = rand() % 10;
printf("I'm process number 1, my pid is %d and my number is %d\n", getpid(), n1);
array[0] = n1;
return 1;
}
if (pid1 > 0){
int pid2 = fork();
if (pid2 == 0){
//write second array element
int n2 = rand() % 10;
printf("I'm process number 2, my pid is %d and my number is %d\n", getpid(), n2);
array[1] = n2;
return 1;
}
}
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
//segmentation fault happens here
printf("%d\n", array[0]);
return 0;
}
You're not checking for a valid return value from shmget.
if (shmid<0){printf("shmget error");exit(1);};
If you did, you would find that the allocation was invalid, because that key_t already exists, try another one - or generate your own unique one:
key_t key = 1;
or
key_t key = ftok("megasuperrandom",'a');
As per "man ftok":
Typically, a best-effort attempt combines the given proj_id byte, the lower 16 bits of the inode number, and the lower 8 bits of the device number into a 32-bit result. Collisions may easily happen, for example between files on /dev/hda1 and files on /dev/sda1.
So you will probably want to loop over some until you find one that works, as an alternative to using ftok().
Also, if you want the children to come up with different random numbers, you will likely want to use a different random function, or move srand() to each child.
Also, you might want to check "man waitpid". It doesn't wait until the process exits, it only waits for a changed state - which is unpredictable. If you want to make sure that the process exited, you will have to check the return status.