Earlier quoted context omitted.
I don't think fork() mandates overcommit. OpenBSD doesn't seem to even allow overcommit or have an OOM killer, memory allocations that exceed available capacity fail immediately even if the memory is not touched.
Let's say you have 1GB RAM. You're running program that occupies 600 MB. Now this program wants to launch second small program that occupies 1 MB. You're doing fork + exec. If you're overcommiting, fork will not reserve another 600 MB, and exec immediately after fork will cause total system usage to be 601 MB. If you're not overcommiting, that fork will fail, because total memory consumption will be 1200 MB which is…
Moving beyond fork() + exec()
261–270 of 358 posts
Re: Moving beyond fork() + exec()
#262Earlier quoted context omitted.
Yeah this seems like a promising discussion.
It has been for decades at this point. thiago's blog posts which introduced me to the topic over a decade ago (and is still one of the best explainers) points out that posix_spawn was introduced in POSIX.1-2001: https://web.archive.org/web/20120718152158/http://www.maciei...
Re: Moving beyond fork() + exec()
#263Earlier quoted context omitted.
Why not?
Because it comes with a lot of overhead and, unless for some reason you really need every of those processes to have their own address space, set of privileges, file descriptors, etc., there's no point in wasting resources repeatedly setting those up only to tear them down milliseconds later. Running the same workloads in an nginx-style process pool usually works better.
Re: Moving beyond fork() + exec()
#264Earlier quoted context omitted.
Should bash link in every program the user might want? Load them up as dynamic libraries?
Node, Python, PowerShell, and the rest do (almost) just that. launchd and systemd famously strived to remove as much shell from the start up process as possible because it was harming boot times and introducing unpredictability.
Re: Moving beyond fork() + exec()
#265The elegance of the fork() + exec() model is that every kind of configuration can be done after the fork using all the usual APIs. Every attempt to replace it with a combined call that I have seen so far seemed fundamentally poorer because it needs to add all configuration options as parameters to the call and then do this in away that you can extend it later and does not become a mess.
I think one problem is that it is already how it is; making an entirely new operating system (that is not Linux, not GNU, and not POSIX) would solve it, but that is not the case here, so it would need to be done as it is.
One possibility would be a new function that creates a new empty child process, but the parent process specifies what system calls the child process executes, and can stop if specifying that exec or exit is (successfully) called by the child process, or if the parent process gives it the program memory to execute directly instead of using a file (since that use is also useful). The new function can still have some of the clone flags available. (I don't actually know how much better it would work.)
There are other possibilities as well.
The existing methods can also remain available for when they are helpful, but functions such as popen might be changed to use the new method.
Re: Moving beyond fork() + exec()
#266Earlier quoted context omitted.
> The things you can do between fork and exec are sometimes underestimated. Off the top of my head, you can call dup2(), you can set a process group id, probably a few other things. What do you mean underestimated? You can do anything between fork and exec; there are no limitations.
That's not true. Just one example, if you do anything with threads you are pretty screwed. For example if another thread holds a mutex at the time of fork(2), and you also want that mutex.
Re: Moving beyond fork() + exec()
#267I just ran into this recently, where I had an obscure bug caused by needing to close more file descriptors in the forked process. "I want a clone of the current process" is just way less common in my experience than "I want a completely new process". It feels crazy that we don't have a way to directly express the latter thing, and can only approximate it by cloning and then fixing things up in post.
Re: Moving beyond fork() + exec()
#268Earlier quoted context omitted.
I don't think fork() mandates overcommit. OpenBSD doesn't seem to even allow overcommit or have an OOM killer, memory allocations that exceed available capacity fail immediately even if the memory is not touched.
Let's say you have 1GB RAM. You're running program that occupies 600 MB. Now this program wants to launch second small program that occupies 1 MB. You're doing fork + exec. If you're overcommiting, fork will not reserve another 600 MB, and exec immediately after fork will cause total system usage to be 601 MB. If you're not overcommiting, that fork will fail, because total memory consumption will be 1200 MB which is…
Does this accounting apply to vfork as well?
Re: Moving beyond fork() + exec()
#269Earlier quoted context omitted.
Even with copy-on-write, fork() still has to pay the setup cost for COW. If the parent process has a lot of busy threads (e.g. Java), you can end up doing a lot of unnecessary COW before exec() fires.
Isn't that what vfork tried to address? No COW, the child starts in its parents address space and only gets its own after calling exec.
> Attempts (such as vfork()) have been made over the years to optimize for this case, but the pattern still is more expensive than it could be.
Basically vfork do a "stop the world".
Re: Moving beyond fork() + exec()
#270Earlier quoted context omitted.
Fork/exec is great if you actually want the traditional copy of your process for some reason. For launching something totally new, like the example in the article of some tool calling git, I think it does make a ton of sense to make something new. Especially since I suspect that is by far the more common case. I suspect “I want a clone of me“ is relatively rarely used at this point.
Relatively rarely, but in some performance sensitive use cases. Mine happens to be fuzzers, where a very cheap fork-like primitive would be a really big win.