QNX 4 interprocess communication is a popular mechanism for 'talking' between software modules, based on the QNX 4 operating system. QNX 4's microkernel architecture implements message passing in such a way that only data locations are transferred between processes, making its IPC for small amounts of data as, or more, efficient than shared memory schemes. Gamma encapsulates most of the common QNX 4 IPC 'C' function calls.
Functions such as qnx_receive and
qnx_reply may be redundant in a program that is using
one of Gamma's built-in event-loop mechanisms. To review the built-in
functionality of Gamma's event loops refer to the section on event loops.
The qnx_name_attach function attaches a 'name' to the
current process. Names, rather than PIDs, are convenient ways to look for tasks
since they are static while the PID of a program will not be.
Names are ASCII strings up to 32 character in length and can be either local
or global. Local names must be unique to the node. Any attempt to register an
existing local name will fail. Global names allow duplication and start with a
slash '/' character. Global names are stored within a name program in QNX 4
called nameloc. When one process wants to look up another
process's name, the qnx_name_locate function is called and
the name to PID mapping is completed.
Gamma>myname = qnx_name_attach(0,"my_app");20
The first argument to the qnx_name_attach function is the
node on which to register the name. If the node number is zero the local node is
assumed. qnx_name_attach returns a name id which is used
with the qnx_name_detach function.
The qnx_name_detach function removes a local or global
name from the local name list or the DataHub instance.
Gamma>qnx_name_detach(0,myname);t
As with the qnx_name_attach function, the first argument
to the qnx_name_detach function is the node number. The
second argument must be the name id returned when attaching the name.
Once a name is registered then the qnx_name_locate
function is useful for locating the task by name. The return value of this
function is a dotted list of the format: (pid . copies)
The pid is the process ID of the located task and copies is
the number of processes that matched the name. Local names must be unique but
there can be multiple instances of global names (those starting with '/').
An example of using the qnx_name_locate function
follows:
Gamma>queue = qnx_name_locate(0,"qserve",0);(91 . 1)
The PID of the qserve task is 91 and there was a single
instance of that registered name found.It is important to assign the return
value of the qnx_name_locate function to a variable since
it is the first number in the list (PID) that is used as an argument to Gamma
functions such as qnx_send,
qnx_receive, qnx_reply,
qnx_vc_attach, and qnx_vc_detach.
The qnx_receive function allows for the Gamma engine to
remain receive-blocked on a specific PID, waiting for a message.
IMPORTANT: If Gamma is being run using a built-in event loop or using the
next_event or next_event_nb
functions then using the qnx_receive function MAY BE
REDUNDANT. Event loops in Gamma have a built-in receive/reply mechanism.
The qnx_send function uses the QNX 4
send C/C++ function to send information between tasks.
The qnx_send function is a synchronous IPC function, and as
such, the sending task waits for the receiving task's reply before continuing.
The qnx_send function can be used to send Gamma
expressions between Gamma modules. Gamma ships with a number of example
programs, of which example 12 demonstrates the use of
qnx_send to transmit and execute a function on another
module. (Examples can be found in /usr/cogent/examples/ directory)
The important excerpts from this example are:
task = car (qnx_name_locate (0, "gui", 1000));
qnx_send (task, stringc (#Arc.fill_color = PgRGB(0xff, 0xff, 0)));
function TitleClock()
{
win.title = date();
}
// Transmit new function
qnx_send (task, stringc (TitleClock));
// Execute new function once.
qnx_send (task, stringc (#TitleClock()));
The communications channel is opened by locating the task using the
qnx_name_locate function and then using
qnx_send. The first qnx_send sends
a command for the receiving task to evaluate, in this case to change the fill
color of an object named 'Arc'. The stringc function is
used to produce an expression that is parse-able.
Next, a new function is defined, passed, and executed on the other task using
two separate qnx_send's.
If you are sending IPC messages to a non-Cogent IPC task the
send_string and send_string_async
functions should be used.