I have a program that's supposed to let two processes alternate between doing a certain task. After the fifth time the child process executes its task it has to destroy a semaphore and the parent process is supposed to stop because of it.
This sounded fairly easy at first, but I'm having difficulty capturing the return value of the sem_wait()
function.
Here's my file:
#include "Part2Defs.h"
int main() {
FILE *fptr = 0;
sem_t *child = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_ANONYMOUS, -1, 0);
sem_t *parent = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_ANONYMOUS, -1, 0);
/* save the number that we'll be writing to the file */
int number = 1, removed = 0;
sem_init(child, 1, 1);
sem_init(parent, 1, 0);
fptr = fopen(BUFFER, "r+");
if(fptr == 0) {
printf("An error occurred while opening the file\n");
}
fprintf(fptr, "%d", number);
fclose(fptr);
int pID = fork();
if(pID == 0) {
/* do this FOREVER. */
while(1) {
/* I was hoping to get the return value here */
if(sem_wait(parent) == 0) {
/* open the file */
fptr = fopen(BUFFER, "r+");
printf("B. The number [] was modified by parent\n");
fclose(fptr);
sem_post(child);
}
else {
printf("--parent-- waiting for new number to be READ: Identifier removed");
}
}
return 0;
}
else if(pID > 0) {
/* make a counter to go from 0 to 5 */
int i = 0;
while(1) {
sem_wait(child);
if(i++ == 5) {
/* delete the semaphore */
sem_destroy(parent);
printf("Semaphore removed\n");
break;
}
/* open the file */
fptr = fopen(BUFFER, "r+");
printf("A. The number [] was modified by child\n");
fclose(fptr);
sem_post(parent);
}
return 0;
}
else {
printf("There was an error creating the fork.\n");
exit(1);
}
}
Here's my output:
A. The number [] was modified by child
B. The number [] was modified by parent
A. The number [] was modified by child
B. The number [] was modified by parent
A. The number [] was modified by child
B. The number [] was modified by parent
A. The number [] was modified by child
B. The number [] was modified by parent
A. The number [] was modified by child
B. The number [] was modified by parent
Semaphore removed
Which is almost exactly what I was hoping for, except the parent process never ended with the message containing the error.
BY THE WAY: this is homework, but I'm supposedly not allowed to add the homework tag on my own post because of my lack of reputation.
sem_wait
's return value only reflects its seccess/failure in acquiring the lock. If you want communication between processes, you need another mechanism (for example, shared memory).
http://man7.org/linux/man-pages/man3/sem_destroy.3.html :
"Destroying a semaphore that other processes or threads are currently blocked on (in sem_wait(3)) produces undefined behavior."
I found a way to use one of the semaphores as a flag to tell the parent when it's done.
#include "Part2Defs.h"
int main() {
FILE *fptr = 0;
sem_t *child = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_ANONYMOUS, -1, 0);
sem_t *parent = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_ANONYMOUS, -1, 0);
/* save the number that we'll be writing to the file */
int number = 1, removed = 0;
sem_init(child, 1, 0);
sem_init(parent, 1, 0);
fptr = fopen(BUFFER, "r+");
if(fptr == 0) {
printf("An error occurred while opening the file\n");
}
fprintf(fptr, "%d", number);
fclose(fptr);
int pID = fork();
if(pID == 0) {
/* do this FOREVER. */
while(1) {
sem_post(child);
sem_wait(parent);
if(!sem_trywait(child))
break;
/* open the file */
fptr = fopen(BUFFER, "r+");
printf("B. The number [] was modified by parent\n");
fflush(stdout);
fclose(fptr);
}
sem_destroy(child);
sem_destroy(parent);
printf("--parent-- waiting for new number to be READ: Identifier removed");
return 0;
}
else if(pID > 0) {
/* make a counter to go from 0 to 5 */
int i = 0;
while(1) {
sem_wait(child);
if(i++ == 5) {
sem_post(child);
sem_post(parent);
//Signal the parent that it's done by adding one to child.
printf("Semaphore removed\n");
break;
}
/* open the file */
fptr = fopen(BUFFER, "r+");
printf("A. The number [] was modified by child\n");
fflush(stdout);
fclose(fptr);
sem_post(parent);
}
return 0;
}
else {
printf("There was an error creating the fork.\n");
exit(1);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.