Send-driven (client/server)
Filesystems, serial ports, consoles, and sound cards all use the client/server model. A C language application program takes
on the role of the client and sends requests to these servers. The servers perform whatever work was specified, and reply
with the answer.
Reply-driven (server/subserver)
One of the more popular reply-driven programs is a fractal graphics program distributed over the network. The master program
divides the screen into several areas, for example, 64 regions. At startup, the master program is given a list of nodes that
can participate in this activity. The master program starts up worker (subserver) programs, one on each of the nodes, and
then waits for the worker programs to send to the master.
An important subtlety
Because the master program is delegating work to worker programs, the master program can't afford to become blocked on any
one program! In a traditional send-driven approach, you'd expect the master to create a program and then send to it. Unfortunately,
the master program wouldn't be replied to until the worker program was done, meaning that the master program couldn't send
simultaneously to another worker program, effectively negating the advantages of having multiple worker nodes.
Multi-threaded server
Multi-threaded servers are indistinguishable from single-threaded servers from the client's point of view. In fact, the designer
of a server can just "turn on" multi-threading by starting another thread.