1/12 Let's talk about posix_spawn, and when to use it.
2/ posix_spawn was reaction to the high cost of fork/exec. It traded off flexibility, and in return, it bought efficient kernel implementations (macOS, FreeBSD, Solaris?), but also permitted user-space implementations built atop fork/exec (Linux).
3/ High cost: fork (in principle) means copying the whole address space. Linux is on-brand with its optimistic COW and OOM killer. It's very fast (until you explode, acceptable risk).
4/ Linux does posix_spawn in user space, on top of fork - but sometimes vfork (an even faster, more dangerous fork). The vfork usage is what can make posix_spawn faster on Linux.
5/ Maybe your fork is not so fast, because your kernel cares about delivering on the memory it promises, or you sweat port rights, or don't have a MMU, etc. Here you can do a kernel-implemented posix_spawn, like xnu and BSD.
6/ Flexibility: You fork, then just write code. Set up the fds and tty etc, then exec. The same system calls you use everyday play double-duty to prepare the child proc. Very clever!
7/ spawn has no such luxury: everything must be wrangled into a declarative API . To reach feature parity, spawn "would need to provide a programming language as a parameter." (That quote is in POSIX!)
8/ What's missing? One hole is the syscall you've never heard of: tcsetpgrp(), which hands-off tty ownership.

The "correct" usage with fork is a benign race, where both the parent (tty donator) and child (tty inheritor) request that the child own the tty.
9/ There is no "correct" tcsetpgrp usage with posix_spawn: no way to coax the child into claiming the tty. This means, when job control is on, you may start a process which immediately stops (SIGTTIN) or otherwise. Here's ksh getting busted: mail-archive.com/ast-developers…
10/ Another hole: error messages. You can call posix_spawn with many file actions: chdir, open, etc. Any of these may fail, but all you get back is a single errno. You don't know *which* file failed to open.
11/ But perf! On my Mac, #fishshell runs /bin/true in 0.87ms, compared to ~1.3ms for bash and zsh. (Amortized 1k runs)

On my Linux box, fish is at 0.22ms, zsh at 0.3, and bash is at 1.4! This is vfork at work.

Run `set -g fish_use_posix_spawn 0`, and fish joins the slow crowd.
12/ So should you use posix_spawn instead of fork? Yes, if you can and want the perf: it's significantly better on both Mac and Linux. But be mindful of the holes!

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with ridiculous fish

ridiculous fish Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @ridiculous_fish

10 Jun 20
1/ I worked at Apple during the Intel and 64 bit transitions. I disagree with this take.
A Mac ARM move really would be about vertical integration. Apple wants to control its roadmaps - same reason they moved iPhone to in-house ARM chips.
Sinfosky argues that vertical integration could be accomplished by offering AMD devices. Dude, that's horizontal, not vertical. Apple would still be at the mercy of someone else's roadmap.
Read 10 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!

Follow Us on Twitter!

:(