user3810155
user3810155

Reputation:

capability of `posix_spawn`

I'm writing a small program which is somewhat a server that spawns its client programs (locally, not over the network) and do interesting things between them. While my primary OS in use is Linux, I expect this to run on other OSes including Windows. There is fork and exec which does the job, but when I port the program to Windows via cygwin, I don't want that crappy fork implemented in cygwin to kick in, which actually calls CreateProcess and copies the current process's memory area to the new process using setjmp/longjmp with shared memory mutexes, all of this in order to be replaced with another program (exec). While reading the FAQ page of cygwin I discovered spawn.h and its posix_spawn, which basically looks like CreatePorcess(Ex) in windows. It seems like a new feature (... I mean not one of the original UNIX system functions), so I have some questions upon it.

  1. Is it implemented well, widely? (I saw some posts on the internet that it is not defined under his/her system.)

  2. Can I expect any performance improvement or deterioration by using posix_spawn instead of fork/exec in Linux?

  3. Why is posix_spawn less known and less used than fork/exec although being standard since 1999?

Upvotes: 2

Views: 2840

Answers (3)

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215397

posix_spawn is not widely implemented, but you should use it when you can anyway.

  • If a platform lacks it, it's always easy to use a drop-in replacement that just does fork-and-exec.

  • If a "native"/optimal implementation is available (either as part of the system, or a drop-in platform-specific one), it will make a big difference for systems where fork is expensive, and even more of a difference for systems that can't do fork at all (MMU-less systems, Windows without something like cygwin, etc.).

  • Even on systems where fork is native and "fast", it can still be rather slow if the parent has lots of virtual mappings, and it's mildly slower than an optimal posix_spawn even for a small parent. See this Twitter thread for some findings: https://twitter.com/RichFelker/status/602313644026761216

As to why it's not more widely used/implemented, it's probably a mix of not being widely known, and the rather klunky, gratuitously object-oriented API design.

Upvotes: 1

According to Linux man pages it appeared in glibc version 2.2 which was released in 2000, and that implementation conforms to POSIX.1-2001 and POSIX.1-2008. I'd expect it to be supported on at least any platform that uses at least this glibc version, as its behaviour can at least be emulated with fork + exec on those platforms.

On Linux you might expect slight performance improvements over fork/exec if vfork is used instead of fork:

The child process is created using vfork(2) instead of fork(2) when either of the following is true:

  • the spawn-flags element of the attributes object pointed to by attrp contains the GNU-specific flag POSIX_SPAWN_USEVFORK; or
  • file_actions is NULL and the spawn-flags element of the attributes object pointed to by attrp does not contain POSIX_SPAWN_SETSIGMASK, POSIX_SPAWN_SETSIGDEF, POSIX_SPAWN_SETSCHEDPARAM, POSIX_SPAWN_SETSCHEDULER, POSIX_SPAWN_SETPGROUP, or POSIX_SPAWN_RESETIDS.

In other words, vfork(2) is used if the caller requests it, or if there is no cleanup expected in the child before it exec(3)s the requested file.

Upvotes: 1

a3f
a3f

Reputation: 8657

  1. Is it implemented well, widely? (I saw some posts on the internet that it is not defined under his/her system.)

The advanced realtime XSI Option Group is optional, so you can conform to POSIX, while not implementing it. But for GNU/Linux, you can count on having it available nowadays.

  1. Can I expect any performance improvement or deterioration by using posix_spawn instead of fork/exec in Linux?

Probably yes, for big processes quite some time could be spent copying page tables only to be discarded at exec time. Implementations of posix_spawn like musl's or glibc's use vfork(2) (or clone(2) directly) when possible in order to avoid this. For systems like cygwin, fork is emulated at a considerable cost and posix_spawn greatly reduces overhead.

  1. Why is posix_spawn less known and less used than fork/exec although being standard since 1999?

Inertia, I guess.

Upvotes: 2

Related Questions