// By Zachary Lilley, Username: lill0017 - Intro to Operating Systems 9/22/24 --Modified 10/25/24 For Programming Assignment #2
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <unistd.h>
#include <semaphore.h> // Added Semaphore Library --10/25/24
#include <fcntl.h> // O_CREAT & O_EXCL --10/25
// Declaring Semaphore Globally
sem_t *sem;
void inc(int *total, int target, int process_id) {
for (int i = 0; i < target; i++) {
sem_wait(sem); // Enter critical section
(*total)++;
sem_post(sem); // Exit critical section
}
printf("From Process %d: counter = %d.\n", process_id
, *total
); exit(0); // Exit after incrementing }
int main() {
int shmid;
int *total;
key_t key = IPC_PRIVATE; // Only grants access to the
// shared memory to parent proccess' children
sem = sem_open("/zachs_sem", O_CREAT, 0666, 1); //Semaphore initialized with a value of 1
if (sem == SEM_FAILED) {
}
// Shared memory for total count
shmid = shmget(key, sizeof(int), IPC_CREAT | 0666); //IPC_CREAT makes the memory segment if it doesn't exist already 0666 gives read, write and execution permissions
if (shmid < 0) { // Validate allocation
}
// Attach total to the shared memory
total = (int *)shmat(shmid, NULL, 0); //cast to int
if (total == (int *) -1) {
}
*total = 0; // Initialize the shared variable once it's allocated
// Fork 4 times
for (int i = 1; i <= 4; i = i + 1) {
int pid = fork();
if (pid == -1) { //Handle fork error and close out semaphore --10/25/24
sem_close(sem);
sem_unlink("/zachs_sem");
}
// For each fork conduct an increment
if (pid == 0) {
// Set target values for each child process
int target = 0;
if (i == 1) target = 100000;
if (i == 2) target = 200000;
if (i == 3) target = 300000;
if (i == 4) target = 500000;
inc(total, target, getpid()); // Pass current PID to inc function
}
}
// Parent processes wait for children
for (int i = 1; i <= 4; i++) {
int pid = wait(NULL);
printf("Child ID: %d exited.\n", pid
); }
// Deallocate and release memory and the semaphore --10/25/24
shmdt(total);
shmctl(shmid, IPC_RMID, NULL);
sem_close(sem);
sem_unlink("/zachs_sem");
printf("End of Simulation.\n"); return 0;
}