I started a week ago understanding and working with semaphores and shared memory, and actually created this program, the problem is i cant find anything wrong with it i been looking at it for hours and everything seems correct.. The code compiles and i can create the build but when i execute it nothing happens ...
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/fcntl.h>
#include <semaphore.h>
#define MAXCHILDS 4
#define MAX_SIZE 10
#define MAX_WRITES 4
typedef struct{
int m[MAX_SIZE][MAX_SIZE];
} matrix;
/*fork variables*/
pid_t child[MAXCHILDS];
/*semphores variables */
sem_t *empty, *full, * mutex;
/*share memory id*/
int shmid;
/*shared memory array pointer */
matrix * sh_mem;
/*pointer to matrix*/
int **p;
void init(){
/*create pointer to matrix*/
p = &sh_mem->m;
/*semaphores unlink and creation */
sem_unlink("EMPTY");
empty=sem_open("EMPTY",O_CREAT|O_EXCL,0700,MAX_WRITES);
sem_unlink("FULL");
full=sem_open("FULL",O_CREAT|O_EXCL,0700,0);
sem_unlink("MUTEX");
mutex=sem_open("MUTEX",O_CREAT|O_EXCL,0700,1);
/*initialize shared memory */
shmid = shmget(IPC_PRIVATE,sizeof(matrix),IPC_CREAT|0777);
/*map shared memory*/
sh_mem = (matrix*)shmat(shmid,NULL,0);
if(sh_mem== (matrix*)(-1)){
perror("shmat");
}
}
void writer(int ** m){
int i,k;
for(i = 0;i<MAX_SIZE;i++){
for(k= 0;k<MAX_SIZE;k++){
m[i][k] = 0;
}
}
}
void reader(int **m){
int i = 0;
int k = 0;
for(i = 0;i<MAX_SIZE;i++){
for(k= 0;k<MAX_SIZE;k++){
printf(m[i][k]);
}
printf("\n");
}
}
void terminate() {
sem_close(empty);
sem_close(full);
sem_close(mutex);
sem_unlink("EMPTY");
sem_unlink("FULL");
sem_unlink("MUTEX");
shmctl(shmid, IPC_RMID, NULL);
}
int main(int argc, char **argv)
{
int i;
init();
for(i = 0;i<MAXCHILDS;i++){
if((child[i]= fork()) < 0) // error occured
{
perror("Fork Failed");
exit(1);
}
if((child[i] =fork())==0){
writer(p);
exit(0);
}
}
/*father*/
reader(p);
wait(NULL);
terminate();
return 0;
}
The childs are supposed to write the the matrix in shared memory, and the father is supposed to read the shared memory array and the print the matrix. Can you help me with this? Thanks for the help ...
You have several problems with your code.
You declare your
p
variable as follows:But the actual type of your array is
int[MAXSIZE][MAXSIZE]
. Although those can both be considered 2-dimensional arrays, they are not at all the same type and do not share the same structure in memory:int **
is a pointer to a pointer to an integer. When used as a 2-dimensional array, it describes a 2-level array. The first level (dereferencing the pointer once) contains an array ofint *
pointers that each point to 1-dimensional arrays of integers.int[MAXSIZE][MAXSIZE]
is a flat 2-dimentional array. It is a single pointer to an array ofMAXSIZE*MAXSIZE
integers. It has the same memory structure as the 1-dimensional arrayint[MAXSIZE*MAXSIZE]
even though it offers the convenience of using 2 levels of subscripts.Passing around pointers to
type[][]
-style arrays in C is non-intuitive and very difficult to get right. I don't advise doing it. You might consider passing pointers to yourmatrix
type instead. Still, it is possible to get it to work with this declaration:then you have to change the
m
parameter inreader
andwriter
toarray2d *m
instead orint **m
and use it as*m
instead of justm
. This gets ugly. Like I said, consider using yourmatrix
type instead.This problem should have been caught by the compiler. It should have been giving you lots of type mismatch warnings. Make sure you always compile with
gcc -Wall
and aim to have your program compile with no errors and no warnings.In
init()
, you setp
too early. You should set it at the end of the function aftersh_mem
has been assigned, not at the start of the function.You are
fork()
ing too many processes in yourmain()
function, as discussed in comments above. You probably meant to callfork()
only once each time through thefor
loop, not twice.You don't wait until the writers have finished filling out the shared memory structure before you go ahead and read its contents.
Note that even if you move your
wait(NULL)
before the call toreader()
, that's not enough, sincewait(NULL)
will only wait for one child process to complete, not all of them.In general, you should compile your program with warnings enabled, pay attention to the warnings, and fix them before wondering what might be wrong with your program. If it still does something unexpected, you should run it under a debugger, use breakpoints, inspect variables, and try to take a look at what's happening. Using these two techniques, you probably would have solved your problem without needing to post here.