Just showing another project I did while I was at Uni.
I dont know if it works, it should work as i submitted it as complete. But knowing me, i probably didnt care if it did work or not.
I’m pretty sure we had to emulate a printer queue. Each printer job was a child process.
Unix based OS only.
Producer
Producer
/* Some printf functions are comment out, these are for debuggin purposes. */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
void fChildProcess();
int main(int argc, char *argv[])
{
if (argc != 3) //Error out if correct command isnt entered
{
printf("Usage: %s SizeOfQueue NumberOfJobs\n", argv[0]);
exit(0);
}
int columns = 2;
int rows;
int row;
int *matrix;
int shmid;
int i, k, j, iNoj, iSoq;
iSoq = atoi (argv[1]);
iNoj = atoi (argv[2]);
if (iNoj > iSoq) //Error if number of jobs is > than the size of the queue
{
printf("Number of Jobs has to be less than the Size of queue\n");
exit(0);
}
FILE *fp;
pid_t pid;
key_t key;
key = 1220; //Identifier for shared memory
rows = iSoq; //Sets the rows in the shared memory to +1 so there is space for flags
k = 1;
/* Makes a file that has the size of the queue in it */
fp = fopen("size", "w");
fprintf(fp, "%d", rows);
fclose(fp);
shmid = shmget(key, sizeof(int)*rows*columns, IPC_CREAT | 0666);
if(shmid < 0)
{
perror("shmget");
_Exit(1);
}
//printf("Segment created\n");
matrix = (int *)shmat(shmid, 0, 0); //Attatch
matrix[0*2 + 0] = 0; // Read/write flag
matrix[0*2 + 1] = 1;
//printf("%d\t%d\n", matrix[0*2 + 0], matrix[0*2 + 1]);
while(1)
{
//printf("WHILE LOOP\n");
if(matrix[0*2 + 0] == 0)
{
for(i = 0; i < iNoj; i++)
{
if(matrix[0*2 + 1] <= iSoq)
{
//printf("FOR LOOP\n");
pid = fork();
if(pid < 0)
{
printf("fork Error");
exit(1);
}
if(pid == 0)
{
fChildProcess();
}
else
{
//printf("PARENT\n");
k = matrix[0*2 + 1];
matrix[k*2 + 0] = pid; //Adds PID to shared memory
matrix[0*2 + 1]++;
printf("PID %d added\n", matrix[k*2 + 0]);
}
}
}
//printf("SHARED MEM\n");
//for(i = 0; i < iSoq; i++)
//{
//printf("%d\t%d\n", matrix[(i+1)*2 + 0], matrix[(i+1)*2 + 1]);
//}
matrix[0*2 + 0] = 1;
}
else
{
sleep(1); //Wait for consumer
wait(1); //Wait for child process
}
}
shmctl( shmid, IPC_RMID, 0 );
}
void fChildProcess()
{
for(;;); //infinite loop, child process runs forever.
}
Consumer
Consumer
/* Some printf functions are commented out, they are used for debugging purpses*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main (int argc, char *argv[])
{
if (argc != 2) //Errors out if correct arguments are not entered
{
printf ("Usage: %s AmmountToDelete\n", argv[0]);
exit(1);
}
int rows;
int columns = 2;
int *matrix;
int shmid;
int i, j, iAtd;
iAtd = atoi(argv[1]);
FILE *fp;
key_t key;
//Opens the size file to get the size of the queue
fp = fopen("size", "r");
fscanf(fp, "%d", &rows);
fclose(fp);
if(iAtd > rows)
{
printf("Please enter a number <= %d\n", rows);
exit(0);
}
k = 0;
key = 1220;
shmid = shmget(key, sizeof(int)*rows*columns, 0666);
if(shmid < 0)
{
perror("shmget"); //Error out if shared mem not found
exit(EXIT_FAILURE);
}
printf("Segment found\n");
matrix = (int *)shmat(shmid, 0, 0); //Attatch
//printf("Shared mem\n");
//for(i = 0; i < rows; i++)
//{
// printf("SHARED MEM\n%d\t%d\n", matrix[i*2 + 0], matrix[i*2 + 1]);
//}
while(1)
{
if(matrix[0*2 + 0] == 1)
{
//printf("SHARED MEM BEFORE\n");
//for(i = 0; i < rows; i++)
//{
// printf("%d\t%d\n", matrix[(i+1)*2 + 0], matrix[(i+1)*2 + 1]);
//}
//printf("KILLING PIDs\n");
for(i = 0; i < iAtd; i++)
{
if(matrix[(i+1)*2 + 0] > 0)
{
printf("KILLING\t%d\n", matrix[(i+1)*2 + 0]);
kill(matrix[(i+1)*2 + 0], SIGTERM); //Kills the process
printf("KILLED\t%d\n", matrix[(i+1)*2 + 0]);
matrix[0*2 + 1]--;
}
}
for(j = 0; j < matrix[0*2 + 1]; j++)
{
matrix[(j + 1)*2 + 0] = matrix[(j + 2)*2 + 0];
}
//printf("SHARED MEM AFTER\n");
//for(i = 0; i < rows; i++)
//{
// printf("%d\t%d\n", matrix[(i+1)*2 + 0], matrix[(i+1)*2 + 1]);
//}
matrix[0*2 + 0] = 0;
}
else
{
sleep(1);
}
}
exit(0);
}