Lecture 19

advertisement
Lecture 19
●
●
●
●
Log into Linux. Copy directory
/home/hwang/cs375/lecture19
Reminder: Project 5 due today.
Project 6 posted, due Thursday, November 12
Questions?
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
1
Outline
●
Introduction to Message Queues
●
System V message queues
●
POSIX message queues
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
2
Introduction to Message Queues
●
●
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 also
can be used for process synchronization.
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
3
System V Message Queues
●
●
●
System V message queues are defined in the
<sys/msg.h> library.
The System V creation and control routines are
similar in format to the semaphore and shared
memory routines.
See examples in msg_server.cpp and
msg_client.cpp
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
4
Creating a Message Queue
●
The msgget( ) routine is used to create a
message queue:
int msgget(key_t key, int flags);
●
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);
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
5
Deleting a Message Queue
●
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);
●
Unlike semaphores and shared memory, the
queue is removed immediately. Any processes
that are waiting on the queue are awakened
and receive an error return.
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
6
Sending Messages (SysV)
●
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 message {
long type;
char data[len];
};
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
7
Sending Messages (SysV)
●
●
The data field of the struct may be an array (or
struct) of any plain 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.
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
8
Receiving Messages (SysV)
●
msgrcv( ) is used to get a message:
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( )).
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
9
Receiving Messages (SysV)
●
●
●
The type parameter allows us to read the next
message of a particular type.
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.)
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
10
Receiving Messages (Sys V)
●
●
If type is less than 0, the first message in the
queue with the lowest type less than or equal to
the absolute value of type is read.
The flg parameter is usually either 0 or
IPC_NOWAIT (if you do not want msgrcv( ) to
block until a message becomes available).
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
11
POSIX Message Queues
●
●
POSIX message queues are defined in the
<mqueue.h> library
To create a POSIX message queue:
mqd_t mq_open(const char *name, int flags, mode_t perms, struct mq_attr *attr);
●
For portability, the name should begin with a
slash and contain no other slashes as was the
case for POSIX semaphores and shared
memory.
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
12
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.
flags can include O_EXCL if you want the call
to fail when the queue already exists. Use
O_NONBLOCK if you do not want mq_send( )
or mq_receive( ) to block.
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
13
POSIX Message Queues
●
●
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.
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.
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
14
POSIX Message Queues
●
To open an existing queue, mq_open( ) is
called with only two arguments:
mqd_t mq_open(const char *name, int flags);
●
A message queue descriptor is returned on
success. On error, -1 is returned and errno is
set appropriately.
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
15
POSIX Message Queues
●
To close a queue use mq_close( ):
int mq_close(mgq_t mqd);
●
To remove a queue use mq_unlink( ):
int mq_unlink(const char *name);
●
The name disappears immediately, but the
queue is not removed until all open queue
descriptors have been closed.
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
16
Sending Messages (POSIX)
●
To send messages use mq_send( )
int mq_send(mqd_t mqd,
const char *msg,
size_t msgsize,
unsigned priority);
●
The priority must be greater than zero.
Messages are placed in the queue in
decreasing priority order.
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
17
Receiving Messages (POSIX)
●
To receive a message:
ssize_t mq_receive(mqd_t mqd,
char *msg,
size_t msgsize,
unsigned *priorityp);
●
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.
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
18
Receiving Messages (POSIX)
●
●
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.
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
19
POSIX Message Queues
●
On Linux, message queues are created in a
virtual file system. You can (optionally) create
and mount this system using:
$ mkdir /dev/mqueue
$ mount ­t mqueue none /dev/mqueue
●
Add the following line to /etc/fstab to mount it
automatically after every reboot:
none /dev/mqueue mqueue defaults 0 0
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
20
In-class Exercise
●
Make copies of the System V example program
files. Modify the copies to use POSIX message
queues instead. (You will need to create two
message queues for the required bidirectional
communication, since there is no message type
in the receive routine.) Recall that the -lrt option
for g++ is needed to compile POSIX IPC
programs.
Tuersday, November 3
CS 375 UNIX System Programming - Lecture 19
21
Download