Live data from Hacker News

Moving beyond fork() + exec()

lwn.net

251–260 of 358 posts

Re: Moving beyond fork() + exec()

#251
post #36

Related to the discussion: "A fork() in the road": https://www.microsoft.com/en-us/research/wp-content/uploads/... > ABSTRACT > The received wisdom suggests that Unix’s unusual combination of fork() and exec() for process creation was an inspired design. In this paper, we argue that fork was a clever hack for machines and programs of the 1970s that has long outlived its usefulness and is now a liability. We catalog t…

> The received wisdom suggests that Unix’s unusual combination of fork() and exec() for process creation was an inspired design. No, it was done that way so that you could launch a program that was too big to fit in memory with the parent program. The original implementation worked by swapping out the forking program to disk on a fork() call. Then, at the moment the program was swapped out but control had not returne…

This comment starts with a no, but agrees with the parent...

Re: Moving beyond fork() + exec()

#252
post #156

Earlier quoted context omitted.

The paper explicitly covers it that various memory COW/snapshot mechanisms are probably faster and safer than the zygote pattern. As it stands getting the zygote pattern correct and safe is something you have to plan for upfront. You can’t retrofit it which is why the paper mentions it has poor composability. Also the advantages of the zygote pattern can be overstated since the memory sharing benefit is minimal since…

In what sense can you not retrofit the zygote pattern?

I recommend at least skimming the paper as it covers this. But essentially you can’t just inject a call at a random point in code to start being a zygote. It’s something you have to plan up front as to the exact point you’re going to fork and that you’re going to do it at the start of program before any threads have started or any files are open and before any locks have been acquired. It’s basically all the challenges of invoking fork at arbitrary points in time.

The reason to do a zygote in the first place could be solved with alternative special APIs that are safer and harder to misuse. But we have fork so there’s not as big of a demand despite the warts.

Re: Moving beyond fork() + exec()

#253
post #41

Earlier quoted context omitted.

Sure, but not many times a second

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()

#254
post #66
post #52

Earlier quoted context omitted.

It’s a hack with many disadvantages. Sometimes a hack is the right answer, but the kernel should it add a primitive for it.

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()

#255
post #132

Earlier quoted context omitted.

It says state. Copy on write still means it's O(number of page table entries) even if you don't copy the contents. It's a well known issue that forking a program with large virtual memory size is slow.

On modern hardware a cow page copy should only take 1-5ms. Redis forks to save the db to disk and it's been a solid design choice. I guess it depends on how sensitive your application is to main thread pauses.

Redis absolutely suffers from long-executing fork() in practice, its developers even griped about it a couple of times on their blog.

Re: Moving beyond fork() + exec()

#256
post #161

Earlier quoted context omitted.

Windows was designed with threads-first mentality because on pre-386 machines you don't have viable process memory protection, so your tasks share memory by necessity. This is not a great argument.

NT was designed to be platform-agnostic, and its original target was the DEC Alpha. Its process model owes nothing to pre-386 CPUs. The WinAPI CreateProcess function is a layer atop NtCreateProcess, so that is where the pre-386 heritage lives. But even the WinAPI process model changed significantly with 32-bit Windows.

No.

https://en.wikipedia.org/wiki/Windows_NT#Development

Windows NT was developed on various different CPUs before the Alpha was a thing. When it was released in 1993, it was released for three CPUs: IA-32, MIPS, and Alpha.

Re: Moving beyond fork() + exec()

#257
Huh, LWN has moved to (sometimes) requiring a click to proceed past the subscription pitch to the actual article. I feel like this may have an inverse effect (insistent begging to the point of inserting additional obstacles = angry/insulted users that are less likely to pay).

Re: Moving beyond fork() + exec()

#258
post #132

Earlier quoted context omitted.

It says state. Copy on write still means it's O(number of page table entries) even if you don't copy the contents. It's a well known issue that forking a program with large virtual memory size is slow.

On modern hardware a cow page copy should only take 1-5ms. Redis forks to save the db to disk and it's been a solid design choice. I guess it depends on how sensitive your application is to main thread pauses.

I have found that design choice to be annoying

Re: Moving beyond fork() + exec()

#259

Earlier quoted context omitted.

It sounds like they're interested in the concept though, just not that specific implementation.

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()

#260

Earlier quoted context omitted.

whereas Unixen have a core task context model of a bunch of threads that by default do not share memory. How are those not simply child processes? I don't understand your use of the word 'threads' here. Does the Unix world not distinguish between threads and processes? In Win32, threads exist within processes, and you can create new threads or child processes.

They are child processes. Second answer: Linux doesn't differentiate between threads and processes. It has a "thread group ID" that serves a small number of purposes, and the rest of the difference is just whether the threads happen to share the same address space.

[deleted]
Post reply on HN