Lecture 19: Message Queues UNIX System Programming Introduction Outline

advertisement
Lecture 19: Message Queues
Introduction
UNIX System Programming
Lecture 19: Message Queues
●
Outline
●
Message queues allow messages (data
packets) to be passed from one process to
another. There can be multiple writers to
the queue as well as multiple readers.
●
Message queues are often used for passing
small messages between processes. They
can also be used for process synchronization.
–
System V Message Queues
– POSIX Message Queues
●
Reference
BLP: Chapter 14
AUP: Chapter 7
– man Pages
–
–
1
2
Lecture 19: Message Queues
Create a Queue
Lecture 19: Message Queues
Delete a Queue
The msgget() routine is used to create a
message queue:
●
int msgget(key_t key, int flags);
●
The msgctl() routine is used to change
permissions on a queue, get information about
the queue and to delete the queue:
// Remove the queue
ret = msgctl(id, IPC_RMID, 0);
●
The routine returns a queue id. Examples:
// Create a named queue
id=msgget(19,IPC_CREAT|IPC_EXCL|0660);
// Access existing queue by name
id=msgget(19, 0);
// Create unnamed queue
id=msgget(IPC_PRIVATE, 0660);
The queue is removed immediately. Any
processes that are waiting on the queue are
awakened and receive an error return.
●
3
4
Lecture 19: Message Queues
Sending Messages
●
Lecture 19: Message Queues
Sending Messages
msgsnd() adds a message to the queue:
msgsnd(int id, void *msg,
size_t len, int flg);
●
id is the queue identifier. msg must be a
pointer to an area of memory that starts with a
long int. The integer is the message type.
msg is usually a pointer to a struct:
struct msg {
long type;
char data[len];
}
5
●
The data field of the struct may be an array
(or struct) of any type. The len parameter is
the size of the data field of the msg struct in
bytes. Note that the len parameter does not
include the size of the integer type field.
flg is usually 0 or IPC_NOWAIT. By default
msgsnd() will block if the queue is full unless
the IPC_NOWAIT flag is set.
●
6
Lecture 19: Message Queues
Receiving Messages
●
Lecture 19: Message Queues
Receiving Messages
msgrcv() is used to get a message:
The type parameter allows us to read the
next message of a particular type.
●
msgrcv(int id, void *msg, size_t len,
size_t type,int flg);
●
id is the queue identifier. msg must be a
pointer to an area of memory just as for
msgsnd(). The len parameter is the size of
the data area in the receiving struct. If the
message is longer than len the message is
removed from the queue and the call fails.
(This can be modified via msgctl()).
●
If type is 0, the first message is read.
If type is greater than 0, the first message in
the queue of that type is read. (Unless flg
contains MSG_EXCEPT, then the first message
NOT of that type is read.)
●
7
8
Lecture 19: Message Queues
Receiving Messages
Lecture 19: Message Queues
POSIX Message Queues
If type is less than 0, the first message in the
queue with the lowest type less than or equal
to the abs. value of type is read.
●
The flg parameter is usually either 0 or
IPC_NOWAIT (if you don't want msgrcv() to
block until a message becomes available).
●
To create a POSIX message queue:
mqd_t mq_open(
const char *name,
int flags,
mode_t perms,
stuct mq_attr *attr);
●
●
For portability the name should begin with a
slash and contain no other slashes.
9
10
Lecture 19: Message Queues
POSIX Message Queues
Lecture 19: Message Queues
POSIX Message Queues
●
The flags argument must contain O_CREAT
or'd (|) with one of O_RDONLY, O_WRONLY or
O_RDWR, depending on whether the creating
process wants to receive or send or both.
●
perms is similar to the permissions on files.
Read and write permission mean the ability to
receive and send messages and execute
permission is meaningless.
●
flags can include O_EXCL if you want the call
to fail if the queue already exists. Use
O_NONBLOCK if you do not want mq_send()
or mq_receive() to block.
●
11
The mq_maxmsg and mq_msgsize fields of
the attr structure set the maximum number of
messages and the maximum message size
respectively. See the man page for details.
12
Lecture 19: Message Queues
POSIX Message Queues
Lecture 19: Message Queues
POSIX Message Queues
●
To open an existing queue mq_open() is
called with only two arguments:
●
To close a queue use mq_close():
int mq_close(mgq_t mqd);
mqd_t mq_open(
const char *name,
int flags);
●
To remove a queue use mq_unlink():
int mq_unlink(const char *name);
A message queue descriptor is returned on
success. On error, -1 is returned and errno is
set appropriately.
●
The name disappears immediately, but the
queue is not removed until all open queue
descriptors have been closed.
●
13
14
Lecture 19: Message Queues
POSIX Message Queues
●
Lecture 19: Message Queues
POSIX Message Queues
To send messages use mq_send()
●
int mq_send(
mqd_t mqd,
const char *msg,
size_t msgsize,
unsigned priority);
To receive a message:
ssize_t mq_receive(
mqd_t mqd,
char *msg,
size_t msgsize,
unsigned *priorityp);
The priority must be greater than zero.
Messages are placed in the queue in decreasing
priority order.
●
●
msgsize is the size of the msg buffer. It
must be at least as big as the queue
mq_msgsize attribute or the call will fail.
15
16
Lecture 19: Message Queues
POSIX Message Queues
Lecture 19: Message Queues
POSIX Message Queues
The oldest message with the highest priority is
received. If the priorityp pointer is non-NULL
then the message priority is returned at that
address.
●
There are also mq_timedsend() and
mq_timedreceive() routines as well as
mq_getattr() and mq_setattr() routines.
You can use mq_notify() to request a signal
when a message arrives in an empty queue.
On Linux, message queues are created in a
virtual file system. You can (this is optional)
create and mount this system using:
●
$ mkdir /dev/mqueue
$ mount -t mqueue none /dev/mqueue
●
17
Add the following line to /etc/fstab to mount
it automatically after every reboot:
●
none /dev/mqueue
mqueue defaults 0 0
18
Lecture 19: Message Queues
In Class Exercise
Download the System V example programs.
Compile and run them. Modify the programs to
use POSIX message queues instead. (You will
need to create two message queues for the
required bidirectional communication.)
●
19
Download