Question: Im not sure how to add semaphores to my code. Assignment Description. The goal of this assignment is to become familiar with semaphores in POSIXbased
Im not sure how to add semaphores to my code.
Assignment Description. The goal of this assignment is to become familiar with semaphores in POSIXbased operating systems. You may have noticed that your fish might have acted a bit erratic! Your assignment is to modify swim_mill which you created with Assignment #3 to include a semaphore to control access to critical resources. Make sure that you have signal handing to terminate all processes, if needed. In case of abnormal termination, make sure to remove shared memory and semaphores as well. Use semget(2), semctl(2), and semop(2) to implement the semaphore. Your semaphore should receive the names of functions passed as parameters. Since different functions are required to access the critical resource, passing the functions as parameters will prove a clean option.
/* The swim mill creates pellet and fish process by forking them as children and
using shared memory to store the fish position and pallet position.
it displays the swim_mill by checking the shared memory's updated position. The
swim_mill also handles signals to begin aborting and clean up.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
//signal flag
int signalFlag = 1;
//test check
void printMem(char * mem);
//signal handler to abort and kill processes
void sighandler(int signum);
int main(int argc, char *argv[])
{
int shmid;//
char grid[10][10];
int fish;
int timer = 0;
int pelletID[18];
int sem_id;
//kill processes handler
signal(SIGINT, sighandler);
key_t key;
key = ftok("swim.txt", 'R');
/*
* Create the segment.
*/
if ((shmid = shmget(key, sizeof(char[22]), IPC_CREAT|0660)) == -1){
perror("could not create memory segment");
}
/*
* Now we attach the segment to our data space.mget.
*/
// Attach the shared memory segment. Exit on error.
char *dataptr = shmat(shmid, NULL, 0);
//SEMAPHORE (key,# of semaphores in that set,permission)
if (( sem_id = semget(key, 1, IPC_CREAT|0660)) == -1){
perror("could not create semaphore");
}
//initialize Semaphore: allows direct control of semaphore information (key,int semnum: identifier of semaphore,int cmd: specifies the operation to be performed)
//if((semctl(sem_id ,0 ,SETVAL, IPC_STAT,sem_union ))== -1){
// perror("semctl error");
//}
//semop - used for changing the value of the semaphore
//semop(id,pointer to an array of structures, semundo:Causes operation to track the changes made)
// if(semop(sem_id, 0,SEM_UNDO) == -1 ){
// perror("semop error ");
//}
//initializing to -1
for(int i = 1; i < 22; i++){
dataptr[i] = -1;
}
//initializing pelletId
for(int i = 0; i < 18; i++){
pelletID[i] = 0;
}
//initializing fish to be in middle position
dataptr[0] = 94;
//# of processe
dataptr[21] = 2;
printMem(dataptr);
//create FISH child
fish = fork();
//check creation of child
if(fish == -1){
perror("fish creation unsuccesful ");
}else if(fish == 0){
//execv(path name of file to be executed,
//Array of pointer to argument.
//Loads and executes a new child process
execv("FISH",NULL);
}
//incrermenter
int idIndex = 0;
while(timer <= 30){
//create second child pellet
if(dataptr[21] < 20) {
dataptr[21]++;
pelletID[idIndex] = fork();
//check creation of child
if(pelletID[idIndex] == -1){
perror("pellet creation unsuccesful ");
}else if(pelletID[idIndex] == 0){
//Loads and executes a new child process
execv("pellet",NULL);
}
idIndex++;
}
//Displays the SWIMMILL, fish position, and pellet position.
for(int i =0; i<10; i++){
for(int j = 0; j<10; j++){
grid[i][j] = '~';//water
for(int k = 1; k < 10; k++) {
if (dataptr[k] > -1 && dataptr[k] < 100)
grid[dataptr[k]/10][dataptr[k]%10] = 'p';//display pellet
}
grid[dataptr[0]/10][dataptr[0]%10] = 'f';//display fish
printf("%c", grid[i][j]);//display
}
printf(" ");
}
//killed
if(signalFlag == 0){
break;
}
sleep(1);
//prints out array in console,
//printMem(dataptr);
timer++;
printf("Timer: %d ", timer);
}//end of while loop
//If signal handler is access
if(signalFlag == 0){
//kill pellet process
kill(fish, SIGINT);
for(int j = 0; j< 18; j++){
if(pelletID[j] != 0){
kill(pelletID[j], SIGINT);
}
}
}
else {
//kill fish
printf("BEGIN SLAUGHTER!!!! ");
printf("killing Fish! ");
kill(fish, SIGUSR1);
//kill pellet process
for(int j = 0; j< 18; j++){
if(pelletID[j] != 0){
printf("Killing pellets! %d ", pelletID[j]);
kill(pelletID[j], SIGUSR1);
}
}
}
//goest to sleep and waits 10 seconds
sleep(10);
shmdt(dataptr);//clean up data detach
//Delete shared memory
shmctl(shmid,IPC_RMID,NULL);
return 0;
}
//signal handler to kill process
void sighandler(int signum){
if(signum == SIGINT){
signalFlag = 0;
}
}
//array check
void printMem(char * mem) {
for(int i = 0; i < 22; i++)
printf("[%d]",mem[i]);
printf(" ");
}
/*
* Pellet process handles the randomized postion of where the pellets will be dropped in swim_mill by
* randomizing a position and storing it in dataptr where its initialized to -1.
* while loop is in charge of moving the pellet down the swimmill. there are also signal handlers to
* abort and clean up that uses
*/
#include
#include
#include
#include
#include
#include
#include
#include
//signal flag
int signalFlag = 2;
//pointer to shared memory segment
char *dataptr;
//signal handler to abort and kill processes
void sighandler(int signum);
int main(int argc, char *argv[])
{
int shmid;
//kill processes handler
signal(SIGINT, sighandler);
//abort and kill processes
signal(SIGUSR1,sighandler);
/*
* allocate the segment.
*/ //location, size, permissions
if ((shmid = shmget(ftok("swim.txt", 'R'), sizeof(char[11]), IPC_CREAT|0660)) == -1) {
perror("Did not allocate segment");
}
// Attach the shared memory segment. Exit on error.
dataptr = shmat(shmid, NULL, 0);
//randomizing pallet
srand(time(0));
//incrementer
int i = 1;
//takes care of randomizing pellet in position where dataptr is -1
for(; i < 21; i++){
if(dataptr[i] == -1){
//random pellet
dataptr[i] = rand()%10 - 10;
break;
}
}
/*while loop finds pellet position in shared memory,
*and updates pellet so it can move down the stream mill.
*Once the pellet reaches the bottom row, the fish will eat it
* or miss it.
*/
while(1){
//pallet moves down
if (dataptr[i] < 90){
dataptr[i] += 10;
}
else {//pallet leaves swim_mill
if(dataptr[i] == dataptr[0]){
printf("chomp pellet ID: %d Position: %d ", getpid(),dataptr[i]);
dataptr[i] = -1;
break;
}
else {
printf("pellet missed pellet ID: %d Position: %d ", getpid(),dataptr[i]);
dataptr[i] = -1;
break;
}
}
//abort and kill process
if(signalFlag == 0){
printf("Sigint received aborting pellet: %d ", getpid());
break;
}
if(signalFlag == 1){
break;
}
//put pellet process to sleep
sleep(1);
}//end of while loop
//print out pellet id
printf("pellet ded %d ", getpid());
dataptr[21]--;
//clean up shared memory detach
shmdt(dataptr);
return 0;
}//end of main
//signal handler to abort and kill process
void sighandler(int signum){
if(signum == SIGINT){
signalFlag = 0;
}
else if(signum == SIGUSR1){
signalFlag = 1;
}
}
//Author Jesus Vargas
//Oct 26, 2017
/*
* FISH process's job is to attacche to shared memory, find Manhattan distance from fish to pallet
* and move towards the best lane. when it receives sigal or abort signal, it breaks out and cleans up
* memory where fish was storing postions.
*/
#include
#include
#include
#include
#include
#include
#include
//signal flag
int signalFlag = 1;
//pointer to shared memory segment
char *dataptr;
//signal handler to abort and kill processes
void sighandler(int signum);
int main(int argc, char *argv[])
{
int shmid;
//kill processes handler
signal(SIGINT, sighandler);
//abort and kill processes
signal(SIGUSR1, sighandler);
/*
* allocate the segment.
*/ //location, size, permissions
if ((shmid = shmget(ftok("swim.txt", 'R'), sizeof(char[11]), IPC_CREAT|0660)) == -1) {
perror("Did not allocate segment");
}
// Attach the shared memory segment. Exit on error.
dataptr = shmat(shmid, NULL, 0);
/*while loop is used to calculate fish to pellet position in order for the
fish to move to the nearest pellets lane */
while(1){
//mimimum lane
int min = 400;
//lane that neares pellet is in
int bestLane = 0;
//Manhattan distance calculations of fish to pellet Manhattan distance
for(int k = 1; k < 11; k++) {
if (dataptr[k] > -1 && dataptr[k] < 100){
int calc = abs((dataptr[0]/10) - (dataptr[k]/10)) + abs((dataptr[0]%10) - (dataptr[k]%10));
if(calc < min){
min = calc;
bestLane = dataptr[k]%10;
}
}
}
//fish moves towards pellet
if(bestLane < dataptr[0]%10){
dataptr[0] -= 1;
}else if(bestLane > dataptr[0]%10 ){
dataptr[0] += 1;
}
//abort and display id
if(signalFlag == 0){
printf("Sigint received aborting fish: %d ", getpid());
break;
}
//put fish process to sleep
sleep(1);
}
//clean up
shmdt(dataptr);
return 0;
}
//signal handler to abort and kill process
void sighandler(int signum){
if(signum == SIGINT){
signalFlag = 0;
}
else if(signum == SIGUSR1){
shmdt(dataptr);
printf("poor fishy is dead!!");
exit(1);
}
}
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
