Message Queues

advertisement
Message Queues
Lecturer: Erick Fredj
1
2003Dr. E. Fredj@
Message Queues
IPC: message queues (MQ)
• are software components used for interprocess (IPC)
communication
• utilize a queue for messaging, i.e. to pass
– control
– data
• work asynchronously:
– sender and receiver do not need to be connected at the
same time
2
2003Dr. E. Fredj@
Message Queues
The Basic idea: How does it work?
• Two (or more) processes can exchange information via access
to a common system message queue.
• The sending process places via some (OS) message-passing
module a message onto a queue which can be read by
another process.
• The receiving process reads the message from the queue
• Each message is given an identification or type so that
processes can select the appropriate message.
• Process must share a common key in order to gain access to
the queue in the first place.
3
2003Dr. E. Fredj@
Message Queues
The Basic idea
4
2003Dr. E. Fredj@
Message Queues
How
to
use
MQ:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
/* gets or create a MQ associated to a key */
int msgget(key_t key, int msgflg)
/* controls the MQ data structure */
int msgctl(int ID, int cmd, struct msqid_ds *buf)
/* stores a copy of the message on MQ */
int msgsnd(int ID, struct msgbuf *msgp, size_t msgsz,int
msgflg)
/* removes a message from the MQ */
ssize_t msgrcv(int ID, struct msgbuf *msgp,
5
Message Queues
size_t
msgsz, long msg-typ, int msgflg)
Initializing the Message Queue
int msgget(key_t key, int msgflg)
key:
– unique key (name) of the message queue
– IPC_PRIVATE: special value for ’key’ – ignores msgflg and
returns ID of message queue on success
msgflg:
– IPC_CREAT: create a new MQ unless it already exists
– IPC_EXCL: useful in combination with IPC_CREAT, call of
msgget() will fail if MQ already exists
returns:
– ID of message queue (on success)
– -1 (otherwise)
6
Message Queues
Send a message to a MQ:
int msgsnd ( int msqid, struct msgbuf *msgp, int msgsz,int msgflg )
msqid: ID of the message queue
msgp: pointer to the message buffer
struct msgbuf { long mtype; /* message type, must be > 0 */
char mtext[MSGSZ]; /* message data */
};
msgsz: size of the msgbuf-member ‘mtext’ in bytes
msgflg: 0 or IPC_NOWAIT (return immediately, do not block)
returns:
– 0 (on success),
– -1 (on error, errno is set)
7
Message Queues
Read and remove a message
from a MQ:
int msgrcv (int msqid, struct msgbuf *msgp, int msgsz, int
msgtype, int msgflg )
msqid, msgp, msgflg: c.f. msgsnd()
msgsz: maximum length msgbuf-member ‘mtext’ in bytes
msgtype: read only messages of this type from the queue
returns:
• 0 (on success),
• -1 (on error, errno is set)
8
2003Dr. E. Fredj@
Message Queues
Message control operations
int msgctl ( int msqid, int cmd, struct msqid_ds *buf )
msqid: ID of the message queue
cmd:
– IPC_STAT – copy info from MQ data structure associated with msgid
into ‚buf‘
– IPC_SET – write a few values of ‚buf‘ into MQ data
structure, e.g.
• msg_perm.uid
• msg_perm.gid
• msg_perm.mode /* only lowest 9-bits */
• msg_qbytes
– IPC_RMID – remove the MQ
buf: used for IPC_SET or IPC_STAT operations
9
Message Queues
Example: msg_send.c
#define MSGSZ 128 /* message size */
typedef struct msgbuf {
long mtype;
char mtext[MSGSZ];
} message_buf; /* Message structure */
int main(int argc, char* argv[])
{
int msqid, msgflg = IPC_CREAT | 0666;
key_t key = 1234;
message_buf sbuf;
size_t buf_length;
fprintf(stderr, "\nmsgget: Calling msgget(%#lx,%#o)\n”,key,msgflg);
msqid = msgget(key, msgflg );
sbuf.mtype = 1; /* We use message type 1 */
strcpy(sbuf.mtext, "Did you get this?"); /* this is the message */
buf_length = strlen(sbuf.mtext) + 1 ;
msgsnd(msqid, &sbuf, buf_length, IPC_NOWAIT); /* Send a message */
printf ("%d, %d, %s, %d\n", msqid, sbuf.mtype, sbuf.mtext, buf_length);
printf("Message: \"%s\" Sent\n", sbuf.mtext);
}10
Message Queues
Example: msg_rcv.c
#define MSGSZ 128
typedef struct msgbuf {
long mtype;
char mtext[MSGSZ];
} message_buf;
int main(int argc, char *argv[])
{
int msqid;
key_t key = 1234;
message_buf rbuf;
/* get the MQ with name “1234” created by the server */
msqid = msgget(key, 0666);
/* get message with type 1 */
msgrcv(msqid, &rbuf, MSGSZ, 1, 0);
printf("%s\n", rbuf.mtext); /* print answer */
exit(0);
}
11
Message Queues
Download