26 Subprocesses (BC)🔗

On Unix and Mac OS, subprocess handling involves fork, waitpid, and SIGCHLD, which creates a variety of issues within an embedding application. On Windows, subprocess handling is more straightforward, since no fork is required, and since Windows provides an abstraction that is a close fit to Racket’s subprocess values.

After Racket creates a subprocess via subprocess (or system, process, etc.), it periodically polls the process status using waitpid. If the process is created as its own group, then the call to waitpid uses the created subprocess’s process ID; for all other subprocesses, polling uses a single call to waitpid with the first argument as 0. Using 0, in particular, can interfere with other libraries in an embedding context, so Racket refrains from calling waitpid if no subprocesses are pending.

Racket may or may not rely on a SIGCHLD handler, and it may or may not block SIGCHLD. Currently, when Racket is compiled to support places, Racket blocks SIGCHLD on start up with the expectation that all created threads have SIGCHLD blocked. When Racket is not compiled to support places, then a SIGCHLD handler is installed.

Using fork in an application that embeds Racket is problematic for several reasons: Racket may install a SIGALRM handler and schedule alarms to implement context switches, it may have file descriptors open that should be closed in a child process, and it may have changed the disposition of signals such as SIGCHLD. Consequently, embedding Racket in a process that forks is technically not supported; in the future, Racket may provide better support for such applications.