8 ms·
fork() is great when you're writing a service. A pattern that I've used repeatedly is: - The initial process reads in configuration files, sets up an environme
by DougWebb 17y ago
fork() is great when you're writing a service. A pattern that I've used repeatedly is:
- The initial process reads in configuration files, sets up an environment, and opens a listening socket for the service. It then forks several times to create service processes. From this point, the initial process' only job is start new service processes when/if they exit or when load increases, and to shutdown the whole service when told to.
- The service processes run in a loop waiting for requests to come in on the socket, which they all share. The service can handle as many concurrent requests as you've got service processes, and they all operate independently. Thanks to copy-on-write, they all access the same configuration information stored in the initial process' memory. When a request comes in, the service process accepts it (which creates a new socket) and does some initial sanity checking to make sure it's a valid request, and then forks to create a handler process to actually process the request. It then goes back to listening for requests.
- The handler process is the workhorse. It gets the connection socket from its parent, and it's still got access to all of the config info. It's an independent process, so it's free to do whatever it needs to, without risk of impacting the continued operation of the service. Once it's done handling the request it can simply exit, freeing up whatever resources it consumed while handling the request.
In this pattern, the initial process and service processes have very simple jobs and very little code, which makes them easier to make bug-free and robust. Having lots of independent processes instead of threads adds robustness, because a crashing process can't take down the other processes in the service (unless it takes the whole machine down, of course.) This is rarely a problem in the initial or service processes, but the handler processes are exposed to the world and are much more likely to encounter unanticipated input, so they're the hardest to make robust. With the pattern, they don't need to be as robust, because they're allowed to exit unexpectedly without harming the service.
- billpg 17y agoThat right there, the perfect use case for fork. Spinning a task off to do its thing in isolation.