×
Samples Blogs Make Payment About Us Reviews 4.9/5 Order Now

Concurrent Processing Homework Solution in Linux

July 10, 2024
Prof. Andrew Bishop
Prof. Andrew
🇬🇧 United Kingdom
Operating System
Prof. Andrew Bishop, a distinguished expert in Linux assignments, holds a Ph.D. from the University of Oxford, United Kingdom. With 18 years of experience, his expertise guarantees precise and comprehensive solutions for all Linux-related challenges.
Tip of the day
Familiarize yourself with OCaml's pattern matching; it simplifies handling recursive data structures like lists and trees, making your code concise and easier to debug.
News
In 2024, Girls Who Code introduced a Data Science + AI track in their free summer programs for high school students, fostering skills in cybersecurity and creative coding​

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.