In the design of an information processing system, it is useful to divide up the code into multiple pieces or modules reduce the context that must be managed in any one module. However, once we divide things up we must design ways in which the pieces can communicate to allow them to contribute to the solution of the entire problem. We need interprocess communication. See
The simplest forms of interprocess communication assumes one thread of control passed cooperatively from a master process to a slave process synchronously, i.e. the master process initialing the hand-off of control will simply wait until the slave process completes its task and returns control. When done within single program, this communications is normally achieved by a function or subroutine call. When done between an application and an operating system, this may also be done by special system traps and interrupts. When done between a master on one system and a slave on another system, or even on the same system in a different program, file system bas and network-based message passing may be used.
In a function call, the master process first prepares a list of input data, save information about its own current state and then transfers control to the slave process giving it the list of input data. The slave process performs its tasks using the list of input data, prepares a list of output data (the return value) and returns control to the master process. A subroutine call differs in not providing a mechanism for a return value, but the distinction is illusory. The input data for a function call may include addresses or pointers that the slave process may use to return information to the master process.
In the function call model, the master process is called the calling routine, the slave process is called the called routine, and the mechanism for transfer of input data and recovery of the returned value is call the calling sequence. The list of input data is called the function argument list.
There are two major types of calling sequences -- ones that allow for recursion and/or multi-threaded use and ones that do not. The ones that do not, typically place the function argument list into a fixed location in either the calling routine or the called routine and saving the state of the calling routine in other fixed locations.
In order to allow for recursion, saved state for the calling process and the function argument list are placed in a stack. The called process either references the function argument list directly from the stack or pops those items off to hold in local storage (usually a second stack). On completion of its work, the called process places the return value onto the top of the stack. The calling process pops the return value from the stack, removes the function argument list from the stack it it has not already been removed from the stack by the called process, and recovers its state from the stack. If the return value is small and appropriate atomic register operations are available, it may be returned via a register instead of on the stack.
If multi-threaded support is needed, either the recursive approach can be used with a common, interlocked stack or each thread can have its own stack. The former approach makes every function call into a critical section, not desirable in general.
When the master process is part of an application and the slave process is part of some common service system, such as an operating system, it is undersirable to give the application sufficient access to the address space of the service system to allow for use of a fucntion calling sequence. In that case the two processes may be isolated from each other and connected by special hardware instructions call traps or interrupts. When a trap or interrupt is executed, the state of the current process is saved (usually on a stack) and control is transferred to another process that may have a separate, isolated address space. If the isolation is complete, the slave process has no way to accept any information from the master process other than the fact that the master called the slave, so usually either the slave is given access to the address space of the master, or at least to the address space of the stack of the master. Careful address tanslation may be needed to access the memory of the master from the slave, but conceptually this is actually a similar situation to a function call.
The simplest way to pass messages between two programs is for one of the two programs to write a file in the file system that the other then reads. Time can be saved and actual storage into the file system can be avoided by the use of pipes. A pipe acts very much like a file being written by one program and read by the other. A named pipe (or fifo) can be found in the file system. If unnamed a pipe can only be found by the process that created it. Pipes are a very efficient interprocess communications mechanism.
Windows named pipes and unix named pipes are a bit different. See . For an example of two programs communicating via a named pipe, see http://www.cs.uml.edu/~fredm/courses/91.308/files/pipes.html, and for a more complete example, http://developers.sun.com/solaris/articles/named_pipes.html.
An alternative to pipes are sockets, which is based on the network, rather than on a file system. While more complex and slower than pipes, sockets alloe the communicating processes to be on different systems, and conceptually they are doing the same thing.
For an example of socket IPC programming, see http://www.cs.cf.ac.uk/Dave/C/node28.html
A third alternative to pipes within a machine is the IPC message queue system. In normal use the IPC message queue system is, as with pipes, confined to use on a single system, and, for as with named pipes, makes use of the file system for interlocking.
Whether using pipes, sockets or message queues, in all three cases, the master establishes the communications link and, when the slave is ready, sends information as a character string. In the synchronous case, the slave waits until something arrives and the master waits until the slave returns its results.
For examples of message queue IPC programming, see http://www.cs.cf.ac.uk/Dave/C/node25.html
Often the connection between processes is more tenuous than a master-slave relationship. For example, a process may be a client to a server. The client has to allow for the possibility that the server may decline or ignore its requests. In this case, the function call model may not work, but all the other models can be arranged to work asynchronously, allowing the client to dispatch a request and check at some later time as to whether it has been processed. Ths is particularly the norm for graphics and data communications.
The most popular peer-to-peer interface is Tk, an extension for Tcl, see http://wiki.tcl.tk/ and http://wiki.tcl.tk/477