Assignment
The goal to write linux homework is to become familiar with concurrent processing in Linux using shared memory. You will implement a license manager that allows a set number of application processes to run. For example, think of an organization that buys five licenses for an application (say, Photoshop). At any given time, only five instances of the application can be executed on the server in this organization. If a sixth person requests a license, the process is put on hold till one of the five licenses is available. Your job is to create the license manager as well as the application such that only the specified number of instances of the application can run.
Solution
License
#include "config.h"
// Initialize object
int initlicense() {
shm->block = 0;
printf("number of licenses available: %d\n", shm->availLicenses);
return shm->childProc;
}
int getlicense() {
if((shm->processes >= shm->availLicenses) || shm->availLicenses == 1) {
shm->block = 1;
} else {
shm->block = 0;
}
return shm->block;
}
// Increment licenses available
int returnlicense() {
shm->childProc--;
return shm->childProc;
}
// Add n licenses to the number available
void addtolicenses(int n) {
shm->childProc - n;
shm->processes--;
}
// Decrements the number of licenses by n
void removelicenses(int n) {
shm->childProc + n;
}
// Log the messages to output file
void logmsg(char *pid, char *c, char *repeat) {
FILE *ofptr;
// Open outfile
if((ofptr = fopen("logfile.data", "a")) == NULL) {
perror("runsim: Error: ");
exit(1);
}
// Append time
addTime(ofptr);
// Print msg to file
fprintf(ofptr, "%s %s of %s\n", pid, c, repeat);
// Close outfile
fclose(ofptr);
}
// Add current time
void addTime(FILE *ofptr) {
time_t tm;
time(&tm);
struct tm *tp = localtime(&tm);
fprintf(ofptr, "%.2d:%.2d:%.2d ", tp->tm_hour, tp->tm_min, tp->tm_sec);
}
Runsim
#include < stdio.h>
#include < string.h>
#include < signal.h>
#include < unistd.h>
#include < sys types.h="">
#include < sys ipc.h="">
#include < sys shm.h="">
#include "config.h"
#define BUFFERSIZE 100
// Shared memory globals
int shmid;
struct nLicenses *shm;
int main(int argc, char *argv[]) {
int numLicenses;
int childCount = 0;
signal(SIGINT, signalHandler);
if(argc > 2) {
printf("runsim: Error: Too many arguments\n");
printf("Usage: ./runsim n < testing.data -- where n is an integer greater than or equal to 1\n");
return 0;
} else if(argc == 1) {
printf("runsim: Error: No argument given\n");
printf("Usage: ./runsim n < testing.data -- where n is an integer greater than or equal to 1\n");
return 0;
}
if(strspn(argv[1], "0123456789") == strlen(argv[1])) {
numLicenses = atoi(argv[1]);
if(numLicenses <= 0) {
printf("runsim: Error: Integer must be greater than or equal to 1\n");
printf("Usage: ./runsim n < testing.data -- where n is an integer greater than or equal to 1\n");
return 0;
}
} else {
printf("runsim: Error: Invalid argument: %s\n", argv[1]);
printf("Usage: ./runsim n < testing.data -- where n is an integer greater than or equal to 1\n");
return 0;
}
// Implement shared memory
key_t key = 5678;
// Create shared memory id
if((shmid = shmget(key, sizeof(struct nLicenses) * 2, IPC_CREAT | 0666)) < 0) {
perror("runsim: Error: shmget ");
exit(1);
}
// Attach shared memory
if((shm = (struct nLicenses *)shmat(shmid, NULL, 0)) == (struct nLicenses *) -1) {
perror("runsim: Error: shmat ");
exit(1);
}
// Init data to shared memory
shm->availLicenses = numLicenses;
shm->processes++;
initlicense();
// Get strings from stdin/file redirection
char buffer[BUFFERSIZE];
char lines[BUFFERSIZE][BUFFERSIZE];
int i = 0, j = 0;
char progName[50] = "./";
char a2[50], a3[50];
while(fgets(buffer, BUFFERSIZE, stdin) != NULL) {
strcpy(lines[childCount], buffer);
childCount++;
}
shm->childProc = childCount;
int terminationTime = 20;
int runningProcesses = 0;
int index = 0;
pid_t pid, child[childCount];
while(terminationTime > 0) {
if(runningProcesses < 20) {
while(getlicense() == 1) {
if(numLicenses == 1) {
terminationTime--;
sleep(1);
if(terminationTime < 0) {
printf("runsim: Error: Did not complete all processes before alloted time limit -- terminating remaining child processes\n");
signalHandler();
exit(1);
}
}
}
if(index < childCount){
// Get program name from lines array
for(i ; lines[index][i] != ' ' ; i++) {
progName[i + 2] = lines[index][i];
}
i++;
// Get sleep time
for(i ; lines[index][i] != ' ' ; i++) {
a2[j] = lines[index][i];
j++;
}
j = 0;
i++;
// Get repeat factor
for(i ; i < strlen(lines[index])-1 ; i++) {
a3[j] = lines[index][i];
j++;
}
i = 0;
j = 0;
removelicenses(1);
pid = fork();
child[index] = pid;
runningProcesses++;
shm->processes++;
printf("running proc: %i\n", shm->processes);
index++;
}
if(pid == -1) {
printf("runsim: Error: Fork error -- terminating program\n");
killProcesses();
exit(1);
} else if(pid == 0) {
char ch[50];
sprintf(ch, "%d", index);
//execl(PATH, argv[0], argv[1], argv[2]);
printf("About to call testsim with arg: %s %s %s %s\n", progName, a2, a3, ch);
execl(progName, "testsim", a2, a3, ch,(char *)NULL);
perror("runsim: Error: ");
}
terminationTime--;
sleep(1);
} else {
printf("runsim: Error: Too many processes running -- killing all then terminating\n");
signalHandler();
exit(1);
}
shm->processes--;
int check = childCheck(child, childCount);
if(check == 1) {
break;
}
}
// Check if there are any remaining child processes runnning
if((wait(NULL) > 0) && (shm->childProc != 0)) {
printf("runsim: Error: Did not complete all processes before alloted time limit -- terminating remaining child processes\n");
signalHandler();
} else {
printf("Completed all %d processes successfully -- terminating program\n", childCount);
killProcesses();
}
return 0;
}
// Check if any children processes are still runnning
int childCheck(pid_t child[], int size) {
int c, status;
for(c = 0 ; c < size ; c++) {
pid_t wid;
wid = waitpid(child[c], &status, WNOHANG);
if(wid != 0) {
child[c] = 0;
}
}
for(c = 0 ; c < size ; c++) {
if(child[c] == 0) {
continue;
} else {
return 0;
}
}
return 1;
}
void signalHandler() {
pid_t id = getpgrp();
killProcesses();
killpg(id, SIGINT);
exit(1);
}
// Terminate all processes
void killProcesses() {
shmctl(shmid, IPC_RMID, NULL);
shmdt(shm);
}
Related Samples
At ProgrammingHomeworkHelp.com, students can explore a diverse range of Operating System assignment samples. These samples cover various topics including Linux, process management, memory allocation, and more. Our expertly crafted samples serve as a valuable resource for students seeking guidance and inspiration for their own assignments. Whether you're struggling with the basics or advanced concepts, our samples offer clear, comprehensive insights. Trust ProgrammingHomeworkHelp.com for top-notch assignment support, helping you achieve academic success in your Operating System courses.
Operating System
Operating System
Operating System
Operating System
Operating System
Operating System
Operating System
Operating System
Operating System
Operating System
Operating System
Operating System
Operating System
Operating System