this is the task i was given as a uni project. - Code after explanation.
The aim of this exercise is to produce a simple simulation of a printer queue within a
UNIX or Linux environment.
The simulation will consist of two communicating processes, a producer and a consumer.
Functional Requirements
First process
This process will be required to run in background to create a series of child processes
that will represent each of the printer jobs. The PID number of each child is to be inserted
/ spooled within a priority queue.
The queue will be made available to the second process to allow de-spooling.
Second Process
This process will be separate from the first and running within a separate console window
and will simulate the de-spooling process.
It should perform the following functions:
Find and delete a number of printer jobs by priority order.
Print a message to notify the user of the deletion.
Kill the corresponding process.
It will be necessary to develop a communication mechanism to transfer data between the
two main processes.
It should be possible to configure the maximum number of jobs allowed within the whole
system.
It should also be possible to configure the consumer and / or the producer to specify how
many jobs they will de-spool or spool during each cycle.
The first process i have called producer and the 2nd destroyer. i get compile errors in windows but not ubuntu. why is this?
also im sure my code could be streamlined. can anyone see any obvious erroneous code?
Cheers.
Code:
/*PRODUCER*/
#include "common.h" /* queue struct and common includes*/
#include <time.h>
#include <assert.h>
/* prototype shutdown */
void progQuit();
long randTYPE();
int main (int argc, char **argv){
/*
* queue ID: qid
* msgflag: ?
* spoolNum: spawn this many processes per loop
* pausetm: time between loops
*
*/
int qid;
int msgflag; // delete
int spoolNum=2;
int pausetm=1;
int pid;
int i;
struct msgBufPid msgBuf;
key_t key =255;
/* handle sigint (ctrl+c) shutdown */
(void) signal(SIGINT,progQuit);
/*CLI
*argv [1] == spoolNum
*argv [2] == pausetm
*/
if (argc!=3){
printf("invalid arguments\n usage:\n [number to spool per cycle] [seconds per cycle]\n");
return -1;
}
if ((spoolNum = atoi(argv[1]))==-1) {
printf("invalid option at [1]\n expected int got %s\n",argv[1]);
return -1;
}
if((pausetm = atoi(argv[2]))==-1){
printf("invalid option at [2]\n expected int got %s\n",argv[2]);
return -1;
}
/* generate KEY */
if((key = ftok("/bin/ls", 62))== -1){
perror("ftok");
return -1;
}
/* create queue connection*/
qid = msgget(key, IPC_CREAT | 0600);
if (qid <= 0){
perror("msgget");
return -1;
}
else {
printf("queue opened/created!, key: %d\n", key);
}
assert(qid > 0);
/*begin spooling */
while(!(breakspawn)){ // primary infinite
sleep(pausetm);
for(i=0;i<spoolNum;i++){
pid = spool();
assert(pid > 0);
assert(qid > 0);
msgBuf.mtype= randTYPE();
msgBuf.pid=pid;
printf("process created\t PID: %d Priority: %d\n", msgBuf.pid, msgBuf.mtype);
if((msgsnd(qid, &msgBuf,(sizeof(msgBuf)-sizeof(long)) ,0)) <0){
perror("msgsnd");
}
}
}
/* delete message queue *
*/
printf("qid == %d", qid);
if((msgctl(qid, IPC_RMID, NULL)) == -1){
perror("msgctl");
exit(-1);
}
printf("sigterm recieved, deleted message queue successfully\n");
exit(0);
}
int spool() {
int pid;
pid = fork();
if (pid < 1){ // if we are in child
for(;;){
sleep(1);
}
printf("pid %d started\n", pid);
}
return pid;
}
void progQuit(){
breakspawn =1;
}
/* random number between 1 and 5 */
long randTYPE(){
srand((unsigned)time(NULL)); // initalise random seed with current epoch
int max =7;
int min =1;
long returnvar;
returnvar = ((long)rand() % (max - min -1)+min); // make sure the random numbers are in the right range
return returnvar;
}
/*
* DESTROYER
*/
#include "common.h"
#include <assert.h>
int main(int argc, char **argv){
/*
* variables
*/
int i;
key_t key = 255;
int qid;
int interval = 1;
int termNum = 3;
struct msgBufPid msgBuf;
/*
* CLI options
*/
if (argc!=3){
printf("invalid arguments\n usage:\n [number to kill per cycle] [seconds per cycle]");
return -1;
}
/* arg 1 processes to kill per cycle */
if ((termNum = atoi(argv[1]))==-1) {
printf("invalid option at [1]\n expected int got %s",argv[1]);
return -1;
}
/* arg 2 pause time */
if((interval = atoi(argv[2]))==-1){
printf("invalid option at [2]\n expected int got %s",argv[2]);
return -1;
}
/* make key */
if((key = ftok("/bin/ls", 62))== -1){
perror("ftok");
return -1;
}
/*open queue*/
if ((qid = msgget(key, 0600))== -1){
perror("msgget");
return -1;
}
assert (qid > 0);
/* endless terminate loop */
for (;;){
sleep(interval);
for(i=0;i<termNum;i++){
/*get message*/
msgrcv(qid, &msgBuf, (sizeof(msgBuf) - sizeof(long)), -5, 0);
/* kill */
kill(msgBuf.pid,15);
printf("\nKILL(%d,15), priority %lu\n",msgBuf.pid, msgBuf.mtype);
}
}
}
#ifndef _COMMON_H
#define _COMMON_H
/* Common header files */
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
/* signal handling */
#include <signal.h>
//program exit flag
static volatile int breakspawn =0;
/* queue struct */
struct msgBufPid {
long mtype;
int pid;
};
#endif /*_COMMON_H */