System
V Message Queues
943
46.2.2
Receiving Messages
The msgrcv() system call reads (and removes) a message from a message queue, and
copies its contents into the buffer pointed to by msgp.
The maximum space available in the mtext field of the msgp buffer is specified by
the argument maxmsgsz. If the body of the message to be removed from the queue
exceeds maxmsgsz bytes, then no message is removed from the queue, and msgrcv()
fails
with the error
E2BIG
. (This default behavior can be changed using the
MSG_NOERROR
flag described shortly.)
Messages need not be read in the order in which they were sent. Instead, we
can select messages according to the value in the mtype field. This selection is con-
trolled by the msgtyp argument, as follows:
z
If msgtyp equals 0, the first message from the queue is removed and returned to
the calling process.
z
If msgtyp is greater than 0, the first message in the
queue whose mtype equals
msgtyp is removed and returned to the calling process. By specifying different
values for msgtyp, multiple processes can read from a message queue without
racing to read the same messages. One useful technique is to have each process
select messages matching its process ID.
z
If msgtyp is less than 0, treat the waiting messages as a priority queue. The first
message of the lowest mtype less than or equal to the
absolute value of msgtyp is
removed and returned to the calling process.
An example helps clarify the behavior when msgtyp is less than 0. Suppose that we
have a message queue containing the sequence of messages shown in Figure 46-1
and we performed a series of msgrcv() calls of the following form:
msgrcv(id, &msg, maxmsgsz, -300, 0);
These msgrcv() calls would retrieve messages in the order 2 (type 100), 5 (type 100),
3 (type 200), and 1 (type 300). A further call would block, since the type of the
remaining message (400) exceeds 300.
The msgflg argument is a bit mask formed by ORing together zero or more of
the following flags:
IPC_NOWAIT
Perform a nonblocking receive. Normally, if
no message matching msgtyp
is in the queue, msgrcv() blocks until such a message becomes available.
Specifying the
IPC_NOWAIT
flag causes msgrcv() to instead return immediately
#include
/* For portability */
#include
ssize_t msgrcv(int
msqid
, void *
msgp
, size_t
maxmsgsz
, long
msgtyp
, int
msgflg
);
Returns number of bytes copied into mtext field, or –1 on error
944
Chapter 46
with the error
ENOMSG
. (The error
EAGAIN
would be
more consistent, as occurs
on a nonblocking msgsnd() or a nonblocking read from a FIFO. However,
failing with
ENOMSG
is historical behavior, and required by SUSv3.)
MSG_EXCEPT
This flag has an effect only if msgtyp is greater than 0, in which case it forces
the complement of the usual operation; that is, the first message from the
queue whose mtype is not equal to msgtyp is removed
from the queue and
returned to the caller. This flag is Linux-specific, and is made available
from
only if
_GNU_SOURCE
is defined. Performing a series of calls
of the form msgrcv(id, &msg, maxmsgsz, 100, MSG_EXCEPT) on the message
queue shown in Figure 46-1 would retrieve messages in the order 1, 3, 4,
and then block.
MSG_NOERROR
By default, if the size of the mtext field of the message exceeds the space
available (as defined by the maxmsgsz argument), msgrcv() fails. If the
MSG_NOERROR
flag is specified, then msgrcv() instead removes the message from
the queue, truncates its mtext field to maxmsgsz bytes, and returns it to the
caller. The truncated data is lost.
Upon successful completion, msgrcv() returns the size of the mtext field of the
received message; on error, –1 is returned.
Chia sẻ với bạn bè của bạn: