Refer to Wikipedia.
You will need to include from sys ipc.h, msg.h, wait.h, and errno.h.
You will have to declare a structure to hold the message that you are going to send. The first part of the message MUST be a long - mtype. After that, you can customize it to your needs.
extern int errno;
#define MSGPERM 0600
int sendverseid;
struct sendverse
{ long mtype;
struct verse{
int childno;
char sheswealloweda[30];
char theverse[200];
}verse;
}qentry;
In order for processes to send/receive messages, a message queue is required. The system call required to obtain a message queue;
Prototype: int msgget (key_t key, int msgflag);
msgqid = msgget(IPC_PRIVATE,MSGPERM|IPC_CREAT|IPC_EXCL)
Like semaphores and shared memory, message queues are permanent. They must be returned to the system. The system has a finite (not large) number of message queues. When a message queue is assigned to a user, that queue is assigned to that user until the user explicitly returns it to the system. If you obtain a message queue and your program terminates without returning it, the message queue is still assigned to you. If you log off, the message queue is still assigned to you. If enough users do this enough times, eventually the system will run out of message queues. Use ipcs and ipcrm to clean up or cs326clean.
The system call required to return a message queue:
rc = msgctl(msgqid,IPC_RMID,NULL);
We will only be accessing the message queues in wait mode. If a process attempts to receive a message from a message queue queue and there is no message queued, the process will be suspended until a message is placed on the queue by another process. If a process attempts to send a message in wait mode and there is no room on the message queue, the process will be suspended. We will always send messages in wait mode.
Important note:Once the message is placed in the queue by the send operation, the sending process continues execution. The sending process is only blocked if the message queue is full. Send and Receive are asynchronous.
int msgsnd (int msqid, struct *msgp, int msgsiz, int msgflg);
int msgrcv (int msqid, struct *msgp, int msgsiz, long msgtyp, int msgflg);
The actual system calls:
To send a message in wait mode:
struct sendverse recite;
rc = msgsnd(msgqid,&recite,sizeof(qentry.verse),0);
A positive (nonzero) value must be placed in recite.mtype This can be used to indicate a message type. In this project, we will not be using a message type, so any nonzero value may be used.
Pay attention to the size of the message; be sure to get it correct.
To receive a message in wait mode:
struct sendverse torecite;
rc = msgrcv(msgqid,&torecite,sizeof(qentry.verse),0,0);
Pay attention to the size of the message; be sure to get it correct.
If msgrcv is called with the flag set to IPC_NOWAIT and there is a message in the queue, it is returned in qentry. If msgrcv is called with the flag set to IPC_NOWAIT and there is no message in the queue, -1 is returned and errno is set to ENOMSG.
The msgtyp parameter in the msgrcv can be used to receive messages out of order.
The sender must set a positive (nonzero) value must be in recite.mtype (see above) This could be used to indicate a message type, but it is not used in this project. can
Although you do not have to submit this, you are strongly encouraged to do the following before starting the deliverable:
Download a skeleton file that compiles oldlady.c. It has constant strings declared for the verses to the rhyme that is to be cooperatively displayed.
Your program is going to consist of a total of 10 processes:
The parent should obtain the message queue. All 9 children will know the message queueid after they are created.
The parent should fork one child. This first child will be considered child 0. It will be the process that receives 8 messages, one from each of the other children. See below.
The parent should then fork 8 more children, children number 1-8. After each fork, the child of the fork should call the child function passing the child number.
The parent should then wait for all 9 children to terminate. After all 9 children have terminated, the parent must return the message queue.
Each child is passed its child number. The number is associated with an entry in the character array swallowed for what was swallowed and an entry in thewords for the verse for that child.
The child should print a message stating it has control and its child number. The child should call getpid to get its pid and print it out. The child should then build a message with its child number, what was swallowed, and the verse. The message should then be sent on the message queue. The child should then terminate.
Child 0 should print a message stating it has control. It should execute getpid to get its pid and print it out.
Child 0 should declare two, two-dimensional character arrays:
Child 0 will have two loops that execute 8 times, one for each verse.
First loop. Child 0 should receive a message, print out the child number it received the message from, and copy the verse into the appropriate entry in the versus character array and what was swallowed in the swallowed array.
Upon termination of the first loop, the rhyme should be assembled
Second loop. This is a nested loop. The outer loop will execute 8 times, one for each verse. Assuming it is a for loop with i=0; i<8;i++, at the top of the loop it should print "There was an old lady who swallowed a " with what was passed as swallowed for this loop iteration. It then should print the verse associated with this iteration. The inner loop should now execute from j=i-1;j>=0;j-- printing the remainder of the verse.
Child 0 should then terminate.
Remember, the operating system buffers output for each process. In order to see the interleaving of processes, you must fflush(stdout) after each printf.
Message queues, shared memory, and semaphores are assigned to a process permanently. They must be returned. When your program crashes, be sure to clean up after yourself using IPCS and IPCRM or use cs326clean. If you do not do this, you will eventually use them all up and no one will be able to get any. You will become very unpopular.
Maintained by Barbara Bracken
Last Modified 3:34 PM 11/10/2024
This page is copyright protected © by Barbara Bracken