|
|
|
|
|
by rwmj
105 days ago
|
|
Not really. It elegantly solves the "create a process, letting it inherit these settings and reset these other settings", where "settings" is an ever changing and expanding list of things that you wouldn't want to bake into the API. Thus (omitting error checks and simplifying many details): pipe (fd[2]); // create a pipe to share with the child
if (fork () == 0) { // child
close (...); // close some stuff
setrlimit (...); // add a ulimit to the child
sigaction (...); // change signal masks
// also: clean the environment, set cgroups
execvp (...); // run the child
}
It's also enormously flexible. I don't know any other API that as well as the above, also lets you change the relationship of parent and child, and create duplicate worker processes.Comparing it to Windows is hilarious because Linux can create processes vastly more efficiently and quickly than Windows. |
|
Or, to quote a paper on deficiencies of fork, "fork() tremendously simplifies the task of writing a shell. But most programs are not shells".
Next. A first solution is trivial: make (almost) all syscalls to accept the target process's pidfd as an argument (and introduce a new syscall to create an empty process in suspended state) — which Windows almost (but not quite) can do already. A second solution would be to push all the insides of the "if (fork () == 0) { ... }" into a eBPF program and pass that to fork() — that will also tremendously cut on the syscall costs of setting up the new process's state as opposed to Windows (which has posix_spawn()-like API).
> create duplicate worker processes.
We have threads for this. Of course, Linux (and POSIX) threads are quite a sad sight, especially with all the unavoidable signalling nonsense and O_CLOFORK/O_CLOEXEC shenanigans.