NetBSD/lib/librt/mq.3

355 lines
10 KiB
Groff

.\" $NetBSD: mq.3,v 1.5 2011/02/26 12:56:35 wiz Exp $
.\"
.\" Copyright (c) 2010 Jukka Ruohonen <jruohonen@iki.fi>
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd July 28, 2010
.Dt MQ 3
.Os
.Sh NAME
.Nm mq ,
.Nm mqueue
.Nd POSIX message queues (REALTIME)
.Sh LIBRARY
.Lb librt
.Sh SYNOPSIS
.In mqueue.h
.Sh DESCRIPTION
The
.St -p1003.1-2001
standard defines and
.Nx
implements an interprocess communication
.Pq Tn IPC
interface known as
.Tn POSIX
message queues.
Although the basic functionality is similar,
.Nm
is distinct from the older
.At V
message queues (see for example
.Xr ipcs 1
or
.Xr msgget 2 ) .
.Ss Rationale
The rationale behind
.Nm
is to provide an efficient, priority-driven asynchronous
.Tn IPC
mechanism.
When the
.At V
message queues were first implemented, the reasoning was similar:
the only form of
.Tn IPC
was half-duplex pipes and message queues were
seen to overcome the performance limitations with these.
.Pp
But arguably in modern systems there is little difference between
the efficiency of the System V message queues, pipes, and
.Tn UNIX
domain sockets (if anything, the
.At V
message queues tend to be slower than the rest).
The fundamental performance bottleneck is however still there with
.Nm
as well: data must be first copied from the sender to the kernel
and then from the kernel to the receiver.
The bigger the message, the higher the overhead.
.Pp
For realtime applications,
.Nm
offers some advantages:
.Pp
.Bl -enum -offset 2n
.It
Unlike the predecessors,
.Nm
provides an asynchronous notification mechanism.
.It
Messages are prioritized.
The queue always remains sorted such that the
oldest message of the highest priority is always received first,
regardless of the number of messages in the queue.
.It
By default, the functions to send and receive messages are blocking calls.
It is however possible to use non-blocking variants with
.Nm .
Furthermore, it is possible to specify timeouts to avoid
non-deterministic blocking.
.It
Resource limits can be enforced \&-- or perhaps more importantly,
the availability of resources can be ensured as the internal
data structures are preallocated.
.El
.Ss Descriptors and Naming
Comparable to pipes and
.Tn FIFOs
.Pq a.k.a. named pipes ,
all
.Tn POSIX
message queue operations are performed by using a descriptor.
The used type is
.Vt mqd_t ,
an abbreviation from a
.Dq message queue descriptor .
In the
.Nx
implementation this is actually an ordinary file descriptor.
This means that it is possible, but not portable, to
monitor a message queue descriptor by using
.Xr poll 2
or
.Xr select 2 .
.Pp
Message queues are named by character
strings that represent (absolute) pathnames.
The used interface is analogous to the conventional file concepts.
But unlike
.Tn FIFOs
and pipes, neither
.Tn POSIX
nor System V message queues are accessed by using
.Xr open 2 ,
.Xr read 2 ,
or
.Xr write 2 .
Instead, equivalents such as
.Fn mq_open ,
.Fn mq_close ,
and
.Fn mq_unlink
are used.
.Pp
The standard does not specify whether
.Tn POSIX
message queues are exposed at the file system level.
It can be argued that
.Nm
inherited an old problem with the System V message queues.
Even if an implementation would have support for it,
it is not portable to view message queues by
.Xr ls 1 ,
remove these with
.Xr rm 1 ,
or adjust the permissions with
.Xr chmod 1 .
.Ss Processes
When a new process is created or the program is terminated,
message queues behave like files.
More specifically, when
.Xr fork 2
is called, files and message queues are inherited, and when the
program terminates by calling
.Xr exit 3
or
.Xr _exit 2 ,
both file descriptors and message queues are closed.
However, the
.Xr exec 3
family of functions behave somewhat differently for
message queues and files: all message queues are
closed when a process calls one of the
.Fn exec
functions.
In this respect
.Tn POSIX
message queues are closer to
.Tn FIFOs
than normal pipes.
.Ss Attributes
All message queues have an attribute associated with them.
This is represented by the
.Va mq_attr
structure:
.Bd -literal -offset indent
struct mq_attr {
long mq_flags;
long mq_maxmsg;
long mq_msgsize;
long mq_curmsgs;
};
.Ed
.Pp
The members in the structure are:
flags set for the message queue
.Pq Va mq_flags ,
the maximum number of messages in the queue
.Pq Va mq_maxmsg ,
the maximum size of each message
.Pq Va mq_msgsize ,
and the number of queued messages
.Pq Va mq_curmsgs .
.Pp
The overall resource requirements for a particular message queue are given by
.Va mq_maxmsg
and
.Va mq_msgsize .
These two can be specified when the queue is created by a call to
.Fn mq_open .
The constraints are enforced through the lifetime of the queue:
an error is returned if a message larger than
.Va mq_msgsize
is sent, and if the message queue is already full, as determined by
.Va mq_maxmsg ,
the call to queue a message will either block or error out.
.Pp
Although there are two functions,
.Fn mq_getattr
and
.Fn mq_setattr ,
to retrieve and set attributes,
resource limits cannot be changed once the queue has been created.
In
.Nx
the super user may however control the global resource limits by using few
.Xr sysctl 7
variables.
.Ss Asynchronous Notification
Instead of blocking in the functions that receive messages,
.Nm
offers an asynchronous mechanism for a process to receive
notifications that messages are available in the message queue.
The function
.Fn mq_notify
is used to register for notification.
Either a signal or a thread can be used as the type of notification; see
.Xr sigevent 3
for details.
.Pp
Bear in mind that no notification is sent for an arrival
of a message to a non-empty message queue.
In other words,
.Fn mq_notify
does not by itself ensure that a process
will be notified every time a message arrives.
Thus, after having called
.Fn mq_notify ,
an application may need to repeatedly call
.Fn mq_receive
until the queue is empty.
This requires that the message queue was created with the
.Dv O_NONBLOCK
flag; otherwise
.Fn mq_receive
blocks until a message is again queued
or the call is interrupted by a signal.
This may be a limitation for some realtime applications.
.Ss Priorities
Each message has a priority, ranging from 0 to the implementation-defined
.Dv MQ_PRIO_MAX .
The
.Tn POSIX
standard enforces the minimum value of the maximum priority to be 32.
All messages are inserted into a message
queue according to the specified priority.
High priority messages are sent before low priority messages.
If the used priority is constant,
.Nm
follows the
.Tn FIFO
.Pq First In, First Out
principle.
.Pp
The basic rule of thumb with realtime prioritization is that low priority
tasks should never unnecessarily delay high priority tasks.
Priority inheritance is not however part of the provided
.Tn API ;
the receiver process may run at low priority even
when receiving high priority messages.
To address this limitation and other potential realtime problems,
the user may consider other functions from the
.Lb librt .
The process scheduling interface described in
.Xr sched 3
can be mentioned as an example.
.Sh FUNCTIONS
The following functions are available in the
.Tn API .
.Bl -column -offset indent "mq_timedreceive " "XXX"
.It Sy Function Ta Sy Description
.It Xr mq_open 3 Ta open a message queue
.It Xr mq_close 3 Ta close a message queue
.It Xr mq_unlink 3 Ta remove a message queue
.It Xr mq_send 3 Ta send a message
.It Xr mq_receive 3 Ta receive a message
.It Xr mq_timedsend 3 Ta send a message with a timeout
.It Xr mq_timedreceive 3 Ta receive a message with a timeout
.It Xr mq_getattr 3 Ta get message queue attributes
.It Xr mq_setattr 3 Ta set message queue attributes
.It Xr mq_notify 3 Ta register asynchronous notify
.El
.Sh COMPATIBILITY
Despite of some early fears, the
.Tn POSIX
message queue implementations are fairly compatible with each other.
Nevertheless, few points can be noted for portable applications.
.Bl -bullet
.It
It is not portable to use functions external to the
.Tn API
with message queue descriptors.
.It
The standard leaves the rules loose with
respect to the message queue names.
Only the interpretation of the first slash character is consistent;
the following slash characters may or may not follow the conventional
construction rules for a pathname.
.It
The length limits for a message queue name are implementation-defined.
These may or may not follow the conventional pathname limits
.Dv PATH_MAX
and
.Dv NAME_MAX .
.El
.Sh SEE ALSO
.Rs
.%A Bill O. Gallmeister
.%T POSIX.4: Programming for the Real World
.%I O'Reilly and Associates
.%D 1995
.Re
.Rs
.%A Richard W. Stevens
.%T UNIX Network Programming, Volume 2: Interprocess Communications
.%V Second Edition
.%I Prentice Hall
.%D 1998
.Re
.Sh STANDARDS
The
.Tn POSIX
message queue implementation is expected to conform to
.St -p1003.1-2001 .
.Sh HISTORY
The
.Tn POSIX
message queue
.Tn API
first appeared in
.Nx 5.0 .
.Sh CAVEATS
User should be careful to unlink message queues at the program termination.
Otherwise it is possible to leave them lying around.