ibm-information-center/dist/eclipse/plugins/i5OS.ic.rzab6_5.4.0.1/cdescriptors.htm

155 lines
11 KiB
HTML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en-us" xml:lang="en-us">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="security" content="public" />
<meta name="Robots" content="index,follow" />
<meta http-equiv="PICS-Label" content='(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))' />
<meta name="DC.Type" content="reference" />
<meta name="DC.Title" content="Descriptor passing between processes—sendmsg() and recvmsg()" />
<meta name="abstract" content="The ability to pass an open descriptor between jobs can lead to a new way of designing client/server applications." />
<meta name="description" content="The ability to pass an open descriptor between jobs can lead to a new way of designing client/server applications." />
<meta name="DC.Relation" scheme="URI" content="aconcepts.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/socketp.htm" />
<meta name="DC.Relation" scheme="URI" content="xdescriptors.htm" />
<meta name="copyright" content="(C) Copyright IBM Corporation 2001, 2006" />
<meta name="DC.Rights.Owner" content="(C) Copyright IBM Corporation 2001, 2006" />
<meta name="DC.Format" content="XHTML" />
<meta name="DC.Identifier" content="cdescriptors" />
<meta name="DC.Language" content="en-us" />
<!-- All rights reserved. Licensed Materials Property of IBM -->
<!-- US Government Users Restricted Rights -->
<!-- Use, duplication or disclosure restricted by -->
<!-- GSA ADP Schedule Contract with IBM Corp. -->
<link rel="stylesheet" type="text/css" href="./ibmdita.css" />
<link rel="stylesheet" type="text/css" href="./ic.css" />
<title>Descriptor passing between processes—sendmsg() and recvmsg()</title>
</head>
<body id="cdescriptors"><a name="cdescriptors"><!-- --></a>
<!-- Java sync-link --><script language="Javascript" src="../rzahg/synch.js" type="text/javascript"></script>
<h1 class="topictitle1">Descriptor passing between processes—<span class="apiname">sendmsg()</span> and <span class="apiname">recvmsg()</span></h1>
<div><p>The ability to pass an open descriptor between jobs can lead to
a new way of designing client/server applications.</p>
<div class="section"><p>Passing an open descriptor between jobs allows one process, typically
a server, to do everything that is required to obtain the descriptor (open
a file, establish a connection, wait for the <span class="apiname">accept()</span> API
to complete) and let another process, typically a worker, handle all the data
transfer operations as soon as the descriptor is open. This design results
in simpler logic for both the server and the worker jobs. This design also
allows different types of worker jobs to be easily supported. The server can
make a simple check to determine which type of worker should receive the descriptor.</p>
</div>
<div class="section"><p>Sockets provide three sets of APIs that can pass descriptors between
server jobs:</p>
<ul><li><span class="apiname">spawn()</span> <div class="note"><span class="notetitle">Note:</span> <span class="apiname">spawn()</span> is not a socket
API. It is supplied as part of the i5/OS™ Process-Related APIs. </div>
</li>
<li><span class="apiname">givedescriptor()</span> and <span class="apiname">takedescriptor()</span></li>
<li><span class="apiname">sendmsg()</span> and <span class="apiname">recvmsg()</span></li>
</ul>
</div>
<div class="section"><p>The <span class="apiname">spawn()</span> API starts a new server job (often
called a "child job") and gives certain descriptors to that child job. If
the child job is already active, then the <span class="apiname">givedescriptor()</span> and <span class="apiname">takedescriptor()</span> or
the <span class="apiname">sendmsg()</span> and <span class="apiname">recvmsg()</span> APIs need
to be used.</p>
</div>
<div class="section"><p>However, the <span class="apiname">sendmsg()</span> and <span class="apiname">recvmsg()</span> APIs
offer many advantages over <span class="apiname">spawn()</span> and <span class="apiname">givedescriptor()</span> and <span class="apiname">takedescriptor()</span>: </p>
<dl><dt class="dlterm">Portability</dt>
<dd>The <span class="apiname">givedescriptor()</span> and <span class="apiname">takedescriptor()</span> APIs
are non-standard and unique to the iSeries™. If the portability of an application
between iSeries and UNIX<sup>®</sup> is
an issue, you might want to use the <span class="apiname">sendmsg()</span> and <span class="apiname">recvmsg()</span> APIs
instead.</dd>
<dt class="dlterm">Communication of control information</dt>
<dd>Often the worker job needs to know additional information
when it receives a descriptor, such as: <ul><li>What type of descriptor is it?</li>
<li>What should the worker job do with it?</li>
</ul>
<p>The <span class="apiname">sendmsg()</span> and <span class="apiname">recvmsg()</span> APIs
allow you to transfer data, which might be control information, along with
the descriptor; the <span class="apiname">givedescriptor()</span> and <span class="apiname">takedescriptor()</span> APIs
do not.</p>
</dd>
<dt class="dlterm">Performance</dt>
<dd>Applications that use the <span class="apiname">sendmsg()</span> and <span class="apiname">recvmsg()</span> APIs
tend to perform slightly better than those that use the <span class="apiname">givedescriptor()</span> and <span class="apiname">takedescriptor()</span> APIs
in three areas: <ul><li>Elapsed time</li>
<li>CPU utilization</li>
<li>Scalability</li>
</ul>
The amount of performance improvement of an application depends on the
extent that the application passes descriptors.</dd>
<dt class="dlterm">Pool of worker jobs</dt>
<dd>You might want to set up a pool of worker jobs so that a server can pass
a descriptor and only one of the jobs in the pool becomes active and receives
the descriptor. The <span class="apiname">sendmsg()</span> and <span class="apiname">recvmsg()</span> APIs
can be used to accomplish this by having all of the worker jobs wait on a
shared descriptor. When the server calls <span class="apiname">sendmsg()</span>, only
one of the worker jobs receives the descriptor.</dd>
<dt class="dlterm">Unknown worker job ID</dt>
<dd>The <span class="apiname">givedescriptor()</span> API requires the server job to
know the job identifier of the worker job. Typically the worker job obtains
the job identifier and transfers it over to the server job with a data queue.
The <span class="apiname">sendmsg()</span> and <span class="apiname">recvmsg()</span> do not require
the extra overhead to create and manage this data queue.</dd>
<dt class="dlterm">Adaptive server design</dt>
<dd>When a server is designed using the <span class="apiname">givedescriptor()</span> and <span class="apiname">takedescriptor()</span>,
a data queue is typically used to transfer the job identifiers from worker
jobs over to the server. The server then does a <span class="apiname">socket()</span>, <span class="apiname">bind()</span>, <span class="apiname">listen()</span>,
and an <span class="apiname">accept()</span>. When the <span class="apiname">accept()</span> API
is completed, the server pulls off the next available job ID from the data
queue. It then passes the inbound connection to that worker job. Problems
arise when many incoming connection requests occur at once and there are not
enough worker jobs available. If the data queue that contains the worker job
identifiers is empty, the server blocks waiting for a worker job to become
available, or the server creates additional worker jobs. In many environments,
neither of these alternatives are what you want because additional incoming
requests might fill the listen backlog. <p>Servers that use <span class="apiname">sendmsg()</span> and <span class="apiname">recvmsg()</span> APIs
to pass descriptors remain unhindered during heavy activity because they do
not need to know which worker job is going to handle each incoming connection.
When a server calls <span class="apiname">sendmsg()</span>, the descriptor for the incoming
connection and any control data are put into an internal queue for the AF_UNIX
socket. When a worker job becomes available, it calls <span class="apiname">recvmsg()</span> and
receives the first descriptor and the control data that was in
the queue.</p>
</dd>
<dt class="dlterm">Inactive worker job</dt>
<dd>The <span class="apiname">givedescriptor()</span> API requires the worker job to
be active while the <span class="apiname">sendmsg()</span> API does not. The job that
calls <span class="apiname">sendmsg()</span> does not require any information about
the worker job. The <span class="apiname">sendmsg()</span> API requires only that an
AF_UNIX socket connection has been set up. <p>An example of how the <span class="apiname">sendmsg()</span> API
can be used to pass a descriptor to a job that does not exist follows:</p>
<p>A
server can use the <span class="apiname">socketpair()</span> API to create a pair of
AF_UNIX sockets, use the <span class="apiname">sendmsg()</span> API to send a descriptor
over one of the AF_UNIX sockets created by <span class="apiname">socketpair()</span>,
and then call <span class="apiname">spawn()</span> to create a child job that inherits
the other end of the socket pair. The child job calls <span class="apiname">recvmsg()</span> to
receive the descriptor that the server passed. The child job was not active
when the server called <span class="apiname">sendmsg()</span>.</p>
</dd>
<dt class="dlterm">Pass more than one descriptor at a time</dt>
<dd>The <span class="apiname">givedescriptor()</span> and <span class="apiname">takedescriptor()</span> APIs
allow only one descriptor to be passed at a time. The <span class="apiname">sendmsg()</span> and <span class="apiname">recvmsg()</span> APIs
can be used to pass an array of descriptors.</dd>
</dl>
</div>
</div>
<div>
<div class="familylinks">
<div class="parentlink"><strong>Parent topic:</strong> <a href="aconcepts.htm" title="Advanced socket concepts go beyond a general discussion of what sockets are and how they work. They provide ways to design socket applications for larger and more complex networks.">Advanced socket concepts</a></div>
</div>
<div class="relref"><strong>Related reference</strong><br />
<div><a href="xdescriptors.htm" title="The sendmsg() and recvmsg() examples show how to design a server program that uses these APIs to handle incoming connections.">Example: Pass descriptors between processes</a></div>
</div>
<div class="relinfo"><strong>Related information</strong><br />
<div><a href="../apis/socketp.htm">socketpair()</a></div>
</div>
</div>
</body>
</html>