Code:
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
int main(void){
key_t key;
int mid;
const int DUMMYMSG = 1;
const int VALIDMSG = 2;
int n = 6; // number of processes
int i, j;
pid_t pids[6];
key = ftok(".", 'A');
// Create Message Queue
mid = msgget(key,IPC_CREAT | 0660);
if(mid ==-1){
perror("Error with msgget\n");
exit(1);
}
// Create msgbuf struct to send/recieve messages
struct msgbuf{
long int mtype;
char mtext[256];
};
struct msgbuf message;
// Create 6 process using fork()
for(i=0; i<n; i++){
if((pids[i] = fork()) < 0){
perror("Error with fork\n");
exit(1);
}
else if(pids[i] == 0){
switch(i){
// case 0-2 will be producers; case 3-5 will be consumers
case 0:
message.mtype = DUMMYMSG;
strcpy(message.mtext,"Dummy Message1");
for(j=0; j<20; j++){
if(msgsnd(mid, (struct msgbuf *) &message, strlen(message.mtext)+1, 0) == -1){
perror("Error in Main:msgsnd switch:0A\n");
exit(1);
}
printf("Consumer1 Sending dummy messages...\n");
usleep(250); // 1/4 of a second
} // for loop 20 times
message.mtype = VALIDMSG;
strcpy(message.mtext,"Valid Message1");
for(j=0; j<60; j++){
if(msgrcv(mid, &message, sizeof(message.mtext)+1, DUMMYMSG, 0) >= 0){
printf("Producer1 Receiving...\n");
usleep(250);
if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){
perror("Error in Main:msgsnd switch:0B\n");
exit(1);
}
printf("Producer1 Sending...\n");
usleep(250);
}
else{
perror("Error in Main:msgrcv switch:0\n");
exit(1);
}
} // for loop 60 times
case 1:
message.mtype = DUMMYMSG;
strcpy(message.mtext,"Dummy Message2");
for(j=0; j<20; j++){
if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){
perror("Error in Main:msgsnd switch:1A\n");
exit(1);
}
usleep(250);
printf("Producer2 Sending dummy messages...\n");
} // for loop 20 times
message.mtype = VALIDMSG;
strcpy(message.mtext,"Valid Message2");
for(j=0; j<60; j++){
if(msgrcv(mid, (struct msgbuf*) &message, sizeof(message.mtext)+1, DUMMYMSG, 0)){
printf("Producer2 Receiving...\n");
usleep(250);
if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){
perror("Error in Main:msgsnd switch:1B\n");
exit(1);
}
usleep(250);
printf("Producer2 Sending...\n");
}
} // for loop 60 times
case 2:
message.mtype = DUMMYMSG;
strcpy(message.mtext,"Dummy Message3");
for(j=0; j<20; j++){
if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){
perror("Error in Main:msgsnd switch:2A\n");
exit(1);
}
usleep(250);
printf("Producer3 Sending dummy messages...\n");
} // for loop 20 times
message.mtype = VALIDMSG;
strcpy(message.mtext,"Valid Message3");
for(j=0; j<60; j++){
if(msgrcv(mid, (struct msgbuf*) &message, sizeof(message.mtext)+1, DUMMYMSG, 0)){
printf("Producer3 Receiving...\n");
usleep(250);
if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){
perror("Error in Main:msgsnd switch:2B\n");
exit(1);
}
usleep(250);
printf("Producer3 Sending...\n");
}
} // for loop 60 times
case 3:
for(j=0; j<60; j++){
if(msgrcv(mid, (struct msgbuf*) &message, sizeof(message.mtext)+1, VALIDMSG, 0)){
printf("Consumer1 receiving...\n");
usleep(250);
message.mtype = DUMMYMSG;
strcpy(message.mtext,"Dummy Message");
if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){ // if a message is recieved, replace with a dummy
perror("Error in Main:msgsnd switch:3\n");
exit(1);
}
printf("Consumer1 sending...\n");
usleep(250);
}
}
case 4:
for(j=0; j<60; j++){
if(msgrcv(mid, (struct msgbuf*) &message, sizeof(message.mtext)+1, VALIDMSG, 0)){
printf("Consumer2 receiving...\n");
usleep(250);
message.mtype = DUMMYMSG;
strcpy(message.mtext,"Dummy Message");
if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){ // if a message is recieved, replace with a dummy
perror("Error in Main:msgsnd switch:4\n");
exit(1);
}
printf("Consumer2 sending...\n");
usleep(250);
}
} // for loop 60 times
case 5:
for(j=0; j<60; j++){
if(msgrcv(mid, (struct msgbuf*) &message, sizeof(message.mtext)+1, VALIDMSG, 0)){
printf("Consumer3 receiving...\n");
usleep(250);
message.mtype = DUMMYMSG;
strcpy(message.mtext,"Dummy Message");
if(msgsnd(mid, (struct msgbuf*) &message, strlen(message.mtext)+1, 0) == -1){ // if a message is recieved, replace with a dummy
perror("Error in Main:msgsnd switch:5\n");
exit(1);
}
printf("Consumer3 sending...\n");
usleep(250);
}
} // for loop 60 times
}
}
}
// wait for the children to exit... then kill process
int status;
pid_t pid;
while (n > 0) {
pid = wait(&status);
printf("\nChild with PID %ld exited with status 0x%x.\n", (long)pid, status);
--n;
}
// remove the queue
if (msgctl(mid, IPC_RMID, (struct msqid_ds*) 0) == -1) {
perror("Error with removing queue in function Main\n");
exit(1);
}
return 0;
}