This below code uses 2 shared memory segments..
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#define KEY_2D 12345
#define KEY_ROW 54321
int main(int argc, char **argv) {
int rows, cols;
scanf("%d %d", &rows, &cols);
if(rows <= 0 || cols <= 0) {
printf("invalid input\n");
return 1;
}
int *dataa_user = NULL; /* To get user input for 2D array */
int i = 0;
int shm_2d = -1;
dataa_user = (int *) malloc(rows * cols * sizeof(int));
/* Do you need to take input from user as 2D array? and then
* convert it back to 1D array?
* I wonder as this is probably your assignment to understand
* some C and Unix concepts
*/
for(i = 0; i < rows * cols; i ++)
scanf("%d", &dataa_user[i]);
/* Creating shared memory that holds 2D array as 1D array */
shm_2d = shmget(KEY_2D, rows * cols * sizeof (int), IPC_CREAT | 0666);
if(shm_2d < 0) {
perror("shmget");
if(dataa_user) free(dataa_user);
dataa_user = NULL;
return 1;
}
/* Attach to the shared memory */
void *data_2d = shmat(shm_2d, NULL, 0);
if(data_2d == (void *)-1) {
perror("shmat");
shmctl (shm_2d, IPC_RMID, NULL);
if(dataa_user) free(dataa_user);
dataa_user = NULL;
return 1;
}
int shm_row = -1;
/* Copy the 1D array to shared memory */
memcpy( data_2d, dataa_user, rows * cols * sizeof(int));
free(dataa_user);
dataa_user = NULL;
/* Creating shared memory to keep the sum of each row as 1D array */
shm_row = shmget(KEY_ROW, rows * sizeof (int), IPC_CREAT | 0666);
if(shm_row < 0) {
perror("shmget");
shmdt(data_2d);
shmctl (shm_2d, IPC_RMID, NULL);
return 1;
} /* this closing brace was missed when i posted it first time.. */
/* Attach to the shared memory */
void *data_row = shmat(shm_row, NULL, 0);
if(data_row == (void *)-1) {
perror("shmat");
shmdt (data_2d);
shmctl (shm_2d, IPC_RMID, NULL);
shmctl (shm_row, IPC_RMID, NULL);
return 1;
}
/* Initialize it to 0. */
memset(data_row, 0, rows * sizeof(int));
for(i = 0; i < rows; i ++) {
if(!fork()) {
int k = 0;
int *dataa_2d = (int *)data_2d;
int *total_row = (int *)data_row;
for(; k < cols; k ++)
total_row[i] += dataa_2d[i * cols + k]; //add data to shm[row index] for each col in that row
return 0;
}
}
int sts = 0;
for(i = 0; i < rows; i ++) {
wait(&sts); /* wait for all the children to exit. */
}
int total_2d = 0;
int *total_row = (int *)data_row;
for(i = 0; i < rows; i ++) {
total_2d += total_row[i]; /* main process adding up all the row sum values */
}
printf("%d\n", total_2d);
/* clean up of IPC(shms used) */
shmdt(data_2d);
shmdt(data_row);
shmctl (shm_2d, IPC_RMID, NULL);
shmctl (shm_row, IPC_RMID, NULL);
return 0;
}
Your problem statement only mandates use of fork() system call.. So, the problem as such is simple (taking advantage of COW)..
(If you were supposed to use exec() system calls, then it might help you understand the reality in linux systems.. Also if totalling of total_row was assigned to each child process, like summing up to 3rd shared memory or something, it would have helped in understanding synchronization.. )
Anyway, hope this helps..
shm*family to get and control the shared memory and semaphores to synchronize. Read manuals and check here cs.cf.ac.uk/Dave/C/node27.html