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).
Moving beyond fork() + exec()
341–350 of 358 posts
Re: Moving beyond fork() + exec()
#342Earlier quoted context omitted.
Unless you want to create a thread in your zygote. Then it breaks down. Raw fork() is terrible. Instead we need a proper primitive to stop and make a snapshot of a process.
You can create threads in the zygote. It doesn't "break down", but sure, there's a bit more work. My trick for that is that the set of threads that I create pre fork have to be suspendable and resumable, preferably lazily (they resume when they are actually needed). So, the zygotes are sitting with those threads suspended. When they become active, they can do work immediately. They might lazily resume those threads a…
Well, yes. You need to wait for all the threads to park themselves at safepoints. This can work if you control the whole runtime, and you don't use something that creates threads behind your back.
This is actually why I've always been interested in a better fork(), it has a lot of parallels with stop-the-world needed for GCs.
> Folks have been saying that it's terrible for as long as I can remember. But it's still there, because it's better than the alternatives
I don't think we have alternatives? Except maybe ptrace()?
Re: Moving beyond fork() + exec()
#343Earlier quoted context omitted.
> 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…
> It was needed back in the era of really expensive memory. Well, it seems we are back in an era with really expensive memory.
Re: Moving beyond fork() + exec()
#344Earlier quoted context omitted.
The problem is that threads are not fault boundaries but processes are. So they're not interchangeable when you care about resilience and misbehaving code.
True, but on Windows the approach is then to use COM servers, which have a faster IPC model, and can even serve multiple clients, depending on how the appartement space is configured.
Re: Moving beyond fork() + exec()
#345Earlier quoted context omitted.
> The problem with fork isn't really that it's slow. The problem is that if you want it to be not-slow, it locks you into a bunch of OS design decisions: you more or less need a memory subsystem where all writable pages are refcounted and copy-on-write when the refcount is bigger than 1 It may not be slow, but for the common case where fork is almost immediately followed by exec in the process where fork returns zero…
Another possible design is instead of forking the current process, you create a new empty process, then the parent calls syscalls to set up the new process, and eventually call exec on the child process. That does mean you either need new syscalls for that, or adapt existing syscalls to take a pidfd as an argument. That also solves some other problems with fork/exec where the default is to inherit a lot of things you…
Create a thread in your own address space, and your process becomes multi-threaded. Create an address space, load some code in it, and create a thread there, and you fork/exec-ed.
In my memory, that OS was MACH, but Google doesn’t confirm that for me.
Re: Moving beyond fork() + exec()
#346Earlier quoted context omitted.
Yes, and CreateProcess needs special facilities to make this possible while in the UNIX model you don't.
Which special facilities are you referring to? If it's the ability to selectively inherit handles (fds) to a new process, Linux's lack of this "special facility" is nothing to be proud of. How do you selectively pass on fds without having a global impact on your process?
Re: Moving beyond fork() + exec()
#347Earlier quoted context omitted.
Which special facilities are you referring to? If it's the ability to selectively inherit handles (fds) to a new process, Linux's lack of this "special facility" is nothing to be proud of. How do you selectively pass on fds without having a global impact on your process?
As explained above, you fork and then before exec you can use all the usual APIs to close/duplicate/... file descriptors. This has no global impact on the parent process because you are already in the child, but one still has access to all the context of the parent needed to whatever configuration you want to do, including things that will be invented in 20 years and are not even conceived today.
There have been plenty of comments here about effective workarounds, multi-process architectures to keep fork cheap, zygotes... these are very specifically working around the problem, while trying to avoid admitting it's a problem.
Re: Moving beyond fork() + exec()
#348Earlier quoted context omitted.
Which special facilities are you referring to? If it's the ability to selectively inherit handles (fds) to a new process, Linux's lack of this "special facility" is nothing to be proud of. How do you selectively pass on fds without having a global impact on your process?
As explained above, you fork and then before exec you can use all the usual APIs to close/duplicate/... file descriptors. This has no global impact on the parent process because you are already in the child, but one still has access to all the context of the parent needed to whatever configuration you want to do, including things that will be invented in 20 years and are not even conceived today.
Re: Moving beyond fork() + exec()
#349Earlier quoted context omitted.
As explained above, you fork and then before exec you can use all the usual APIs to close/duplicate/... file descriptors. This has no global impact on the parent process because you are already in the child, but one still has access to all the context of the parent needed to whatever configuration you want to do, including things that will be invented in 20 years and are not even conceived today.
And as noted elsewhere, what you want is a new process with a specific fd: duplicating your current process state is a path-dependent evolution, rather than a logic step. There have been plenty of comments here about effective workarounds, multi-process architectures to keep fork cheap, zygotes... these are very specifically working around the problem, while trying to avoid admitting it's a problem.
Re: Moving beyond fork() + exec()
#350Earlier quoted context omitted.
And as noted elsewhere, what you want is a new process with a specific fd: duplicating your current process state is a path-dependent evolution, rather than a logic step. There have been plenty of comments here about effective workarounds, multi-process architectures to keep fork cheap, zygotes... these are very specifically working around the problem, while trying to avoid admitting it's a problem.
You are changing your argument. Let's first agree that my point that being able to use standard APIs (dup,close,pipe,...) is elegant and avoids having a lot of parameter for a process creation call.
It's an achievable result with less specialised parts, but there's a reason we don't write all of our logic in NAND gates.
I'm still only inferring what you meant by CreateProcess needing special facilities; I assume you meant opt-in fd inheritance. Saving a parameter call while forcing all fds to be shared/duplicated seems penny-wise but pound-foolish.