3 ms·
Jobs, more precisely, nested jobs, are one of the best things (IMHO) that were added to Windows 8 from a technical point of view (then again, there ain't many g
by Joker_vD 6y ago
Jobs, more precisely, nested jobs, are one of the best things (IMHO) that were added to Windows 8 from a technical point of view (then again, there ain't many good things added in Windows 8). I had to write a work-manager sort of application that would need to start worker subprocesses (which may also start some other subprocesses, which may or may not be programs under my control) and one of the requirements was that if the main process crashed, all the worker processes should be terminated (imagine if a part of what a worker process is supposed to do is to listen on some well-known TCP ports and provide an HTTP API on it: you can't restart the main process without killing the workers off first).
On Linux, it turned out to be surprisingly tricky. Process groups and sessions are not nested, you can easily break out of them and in fact there were some programs we needed to use that insisted on doing daemonization. Thankfully the most important one had a "--foreground" flag but it still was buggy: this program sends SIGTERM to its process group as part of a shutdown — so it kills its parent, too. Amazing. In the end I believe we ended running each worker process as a separate Docker container.
Then there is a dance of waiting (or not waiting? SIGCHILD is truly horrible) on children PIDs to detect the crashes and unexpected hang in the shutdown (the worker process sends "I am done" notification to the parent, but then for some reason doesn't exit). The main process had to be made a sub-reaper to do all of that more or less reliably, and even then there were some strange sightings (signal handling is fun!).
On Windows, we just shoved each worker process into its own unbreakable-from job, and that was it. The main process dies for whatever reasons, its children just disappear. A worker process dies, its children just disappear, without affecting any other worker processes and their children. Detecting termination of the child processes too was a breeze: on Windows, when you spawn a child process you get not only its PID, but also a handle (think "file descriptor") to it. This handle refers exactly to this process, and you can (interruptibly) wait on it, and when the last open descriptor to a process is closed, the process is deleted from the process table. That's why BTW there is no PID 1 that is constantly reaping its children on Windows: each process implicitly has its own handle alway open, so if the parent exits before the child does, nothing bad happens: The child process had 2 open handles on it, now it has 1. When it itself exits, the last handle is dropped, and the slot in the process table is cleaned.
TL;DR: Process management is horrible, use Erlang.