So I am trying to understand how semaphores with forks. I have written a C program which forks once and passes an integer, via a pipe, from the child pid to the parent pid 4 times. So I have been able to successfully read/write with a pipe between the forked children. However, I run into problems when I attempt to loop multiple writes to my pipe. I am attempting to regulate my pipe with semaphores in order to obtain alternating write, read, write, read, etc. My code with semaphores now generates SEGFAULTS or just hangs after printing out my header. I know I can accomplish this regulation with another pipe but I am specifically doing this to better understand semaphores. I have been reading an OS book but it is not really clicking; can anyone explain this to me via my code example? (This is not Homework)
/*****PROTOTYPES*****/
int SpawnBots();
void sender(int fd[2], sem_t *sem);
void receiver(int fd[2], sem_t *sem);
int exp(int base, int exponent);
int main(int argc, char *argv[]) {
printf("WELCOME...\n");
SpawnBots();
return 0;
}
int SpawnBots() {
sem_t *sem = sem_open("test_semaphore", O_CREAT | O_EXCL, 1, 1);
sem_unlink("test_semaphore");
int fd[2]; //0=input 1=output
pid_t pid;
//sem_init(sem, 1, 1);
pipe(fd);
pid = fork();
if(pid==0) {
//pid=0 is child
sender(fd, sem);
} else {
//pid!=0 is parent
receiver(fd, sem);
}
return 0;
}
void sender(int fd[2], sem_t *sem) {
//child closes read pipe
fflush(stdout);
close(fd[0]);
int val;
char buffer[32];
//writes 4 numbers to stdout
for(int i=1; i<=4; i++) {
sem_wait(sem); //takes control; waits for read from receiver()
val = exp((i+3), i);
printf("\tChild %d: \t%d\n", i, val); //prints out current data its writing
sprintf(buffer, "%d", val);
write(fd[1], buffer, strlen(buffer) + 1); //writes to stdout
sem_post(sem); //hands back control
}
close(fd[1]);
sem_close(sem);
exit(0);
}
void receiver(int fd[2], sem_t *sem) {
//child closes write pipe
//fflush(stdout);
close(fd[1]);
int val;
int i=1;
int nbytes=1;
char buffer[32];
//reads in numbers until stdout is empty
while(1) {
sem_wait(sem); //takes control; waits for write from sender()
if((nbytes = read(fd[0], buffer, sizeof(buffer)+1)) > 0) { //reads from stdout
val = atoi(buffer);
printf("\tParent %d: \t%d\n", i, val); //prints out current data its reading
i++;
} else {
break;
}
sem_post(sem); //hands back control
}
sem_post(sem);
close(fd[0]);
sem_close(sem);
exit(0);
}
int exp(int base, int exponent) {
int output = 1;
for(int i=1; i<=exponent; i++) {
output = output * base;
}
return output;
}