Fork has really weird semantics, and a lot of fun gotchas around managing resources. Good riddance?
A fork() in the road
31–40 of 184 posts
Re: A fork() in the road
#32The paper also mention the use case of multiprocess servers which relies heavily on fork() but dismiss it as it could be implemented with threads. A crash in a worker would lead to the crash of the whole application. While a worker could just be restarted.
A proper use case of removing fork() from an actual program would help. For example, how nginx on Windows is implemented?
Re: A fork() in the road
#33Re: A fork() in the road
#34Fork has really weird semantics, and a lot of fun gotchas around managing resources. Good riddance?
Not even just the semantics, the performance is awful. Even when the fork is virtual (as any modern fork is) and there's no memory copying because it's COW, all the kernel page tables still need to be copied and for a multi-GB process that's nontrivial. That's why any sane large service that needs to fork anything will early on start up a slave subprocess whose only job is to fork quickly when the master process need…
I don't think that's (entirely) true. This is more because a large service with some potent master process will have said process Do Stuff(tm) that will involve opening files, threads, signal handling, or whatever things that need to be taken care of one way or the other when forking to a worker (or whatever other child) process. It's therefore much simpler to fork a master subprocess into a child spawner earlier on, when it has yet to do anything. You significantly reduce your chances of screwing up if you have nothing to clean up for.
Re: A fork() in the road
#35I read the paper, and they make a lot of good points about fork's warts. But I really wanted some explanation of why Windows process startup seems to be so heavyweight. Why does anything that spawns lots of little independent processes take so bloody long on Windows? I'm not saying "lots of processes on Windows is slow, lots of processes on Linux is fast, Windows uses CreateProcess, Linux uses fork, CreateProcess is…
Re: A fork() in the road
#36Earlier quoted context omitted.
Not even just the semantics, the performance is awful. Even when the fork is virtual (as any modern fork is) and there's no memory copying because it's COW, all the kernel page tables still need to be copied and for a multi-GB process that's nontrivial. That's why any sane large service that needs to fork anything will early on start up a slave subprocess whose only job is to fork quickly when the master process need…
> That's why any sane large service that needs to fork anything will early on start up a slave subprocess whose only job is to fork quickly when the master process needs it. I don't think that's (entirely) true. This is more because a large service with some potent master process will have said process Do Stuff(tm) that will involve opening files, threads, signal handling, or whatever things that need to be taken car…
I just did a quick test, a 100mb process generally takes >2ms to fork, while a 1mb or less process takes 70us. It seems like its pretty much linear with process size.
Re: A fork() in the road
#37Fork has really weird semantics, and a lot of fun gotchas around managing resources. Good riddance?
* redirect stdin, stdout, and stderr
* open files that might be needed and close files that aren't
* change process limits
* drop privileges
* change the root directory
* change namespaces
And there are a few other things I am probably forgetting.Re: A fork() in the road
#38Earlier quoted context omitted.
Can't you use posix_spawn() with WSL and your favorite POSIX-compatible libc implementation?
Well that's a complicated question to answer. You can use the posix_spawn function in glibc, which uses a vfork or clone syscall just like on Linux.
https://mobile.twitter.com/RichFelker/status/602313979894038...
"Rich Felker, May 24, 2015: Some interesting preliminary timing of @musllibc 's posix_spawn vs fork+exec shows it ~25x faster for large parent processes. (~360us vs 9ms). #glibc has a vfork-based posix_spawn but it's only usable for trivial cases; others use fork. @musllibc posix_spawn always uses CLONE_VM. This also means @musllibc posix_spawn will fill the fork gap on NOMMU systems cleanly/safely (unlike vfork) once we get NOMMU working."
Also evilotto's post here:
https://news.ycombinator.com/item?id=19622477
"a 100mb process generally takes >2ms to fork, while a 1mb or less process takes 70us"
Re: A fork() in the road
#39Fork has really weird semantics, and a lot of fun gotchas around managing resources. Good riddance?
Between the `fork()` and an `exec()`, I can: * redirect stdin, stdout, and stderr * open files that might be needed and close files that aren't * change process limits * drop privileges * change the root directory * change namespaces And there are a few other things I am probably forgetting.
Re: A fork() in the road
#40However, may I point out that Microsoft SQL Server benchmarks have been posted that show Linux TCP-H outperforming Windows?
https://www.dbbest.com/blog/running-sql-server-on-linux/
While I am sure that this is wise criticism, it might also be concluded that Windows itself contains no small amount of architectural decisions that limit performance.