1. INTRODUCTION
2. REQUIREMENTS
3. INSTALLATION
4. USING THE TOOL ZZ
5. USING THE ZZ TOOLS
6. KNOWN BUGS AND LIMITATIONS
7. COPYRIGHT AND LICENSE
8. CONTACTING THE AUTHOR
ZZ is a framework for flexible, easy and efficient inter-process communication under Unix. It is optimized for large data transfers between unrelated processes. ZZ builds upon and improves the concept of shell pipes.
ZZ allows starting a number of executables with one shell command, defining an arbitrary network of data channels between them. ZZ data channels are based on shared memory, and thus, unlike pipes, require no copying at all between the producer and the consumer processes. The producer process allocates a chunk of memory, for instance an image, fills the chunk with data, and sends the consumer process a handle to the memory chunk, along with metadata. The consumer process reads from the same location where the data was created. This requires less memory and CPU time than using a pipe.
ZZ consists of two parts; an executable called zz which creates channels and launches processes, and the C library libzz which adds ZZ support to applications. The ZZ package also includes general-purpose tools, such as zzcast which broadcasts to all peers, and zzlisten which is a debugging tool, logging all traffic.
ZZ depends on the Unix API and Glib. You need a POSIX- and SysV-compliant operating system, and at least version 2.0 of Glib, which is part of the Gnome/GTK+ libraries. ZZ has not been tested on a wide variety of systems. It is mainly being developed on a Fedora Core 2 (kernel 2.6.5) Linux system on an AMD Athlon, with Glib 2.4.0.
Edit Makefile to suit your needs and system, if necessary. The default installation directory is /usr/local. Run make install to compile and install. Run make uninstall to uninstall.
The tool zz is used to launch applications connected by ZZ data channels, much the same way as the shell pipe operator | is used. Its help screen is:
Usage: zz [options] command... , with options:
-h --help This help screen
-d --dump Dump all data, for debugging
-p --pretend Pretend to spawn, for debugging
After entering zz (and options), application commands are entered one after another, where each application command ends in one or more socket declarations. Each data channel must have a unique name, and one producer (output) socket (spelled name@), and one consumer (input) socket (spelled name%). Thus, to start the applications foo and bar with a channel called "a" from foo to bar, enter:
zz foo a@ bar a%
To also start goo which takes input from bar via a channel called "b", enter:
zz foo a@ bar a% b@ goo b%
...which reminds of a pipe chain, such as foo | bar | goo. However, ZZ is not limited to a straight chain. We might add a channel "c" from goo to foo, thus forming a ring:
zz foo c% a@ bar a% b@ goo b% c@
This raises a question; when do the applications exit? A one-way chain usually exits when the input is exhausted. What about feedback loops? This is entirely application-defined. An application may choose to exit any time, and this will be detected by its peers, which as a result might also choose to exit. zz itself exits when all applications have exited. zz and libzz are built to exit cleanly upon SIGINT, which means that you can safely press Ctrl-C to abort zz and the applications it has launched.
The function of an input or output socket is also entirely defined by the application. For instance, a video multiplexing application might expect a video stream on the first input, and an audio stream on the second input. This might look like multiplexor video% audio% out@. Entering multiplexor audio% video% out@ would be an error, as the ordering is wrong. Inputs and outputs may be mixed freely in the command, thus multiplexor video% out@ audio% is equally valid. The outputs are numbered from 0 upwards, and the inputs are numbered independently from 0 upwards. In this example, video would be input 0, audio would be input 1, and out would be output 0. There is no technical difference between an input and an output, but it is convenient to agree on a producer role on one side of a channel, and a consumer role on the other side.
zz has some options which aid debugging. When debugging a script which uses zz, invoking the options -d -p might be useful as zz then only prints exactly what it would have done.
Finally, to show off the power of zz, imagine the applications loadimg, saveimg, rgbsplit, rgbjoin, contrast and invert with which we want to raise the contrast by 10% in the red channel and invert the green channel in a series of images called img0001.png, img0002.png and so on. We would do this with the command:
zz loadimg img%04d.png a@ rgbsplit a% r1@ g1@ b@ contrast 10 r1% r2@ invert g1% g2@ rgbjoin r2% g2% b% c@ saveimg new-img%04d.png c%
The ZZ software package comes with a number of tools which aid debugging and might be useful along with zz:
Additionally, the makefile in the source directory defines several tests:
The maximum size of a block of shared memory is limited to SHMMAX by the operating system. The Linux kernel allows changing SHMMAX by entering echo 60000000 >/proc/sys/kernel/shmmax or similar.
The entire ZZ package is copyrighted by Tom Weber in 2004, and licensed under the GNU General Public License. Refer to the file COPYING for more information.
All questions, patches and feedback, whether positive or negative, are most welcome.