Live data from Hacker News

Fork() without exec() is dangerous in large programs

evanjones.ca

41–50 of 106 posts

Re: Fork() without exec() is dangerous in large programs

#41

Earlier quoted context omitted.

Non-unix systems don't have exec; they have spawn.

Windows has exec.

Exec is substitution of current process with new image without closing fds or changing pid. Which winapi function does that?

Re: Fork() without exec() is dangerous in large programs

#42

Earlier quoted context omitted.

Non-unix systems don't have exec; they have spawn.

Windows has exec.

Right, but it's not used in the sense of fork+exec. I should have said that Windows doesn't only have exec, it has spawn too.

Re: Fork() without exec() is dangerous in large programs

#43
It sounds like if you use threads and fork it might be a disaster. Its true, but the author blames only fork and skip the second part of the problem, threads. This is not fair, because fork is much older than POSIX threads. In fact, POSIX threads were poorly designed to use with fork.

Re: Fork() without exec() is dangerous in large programs

#44
post #41

Earlier quoted context omitted.

Windows has exec.

Exec is substitution of current process with new image without closing fds or changing pid. Which winapi function does that?

_wexec and friends. It internally uses CreateProcess obviously.

Re: Fork() without exec() is dangerous in large programs

#45
post #18

Earlier quoted context omitted.

I would like to see the reasons this comment was down-voted. It is true that fork(2) is simple and elegant design, but it involves a huge accidental complexity and hidden implications like in the original article. There is a reason that Linux has clone(2) underneath.

> It is true that fork(2) is simple and elegant design What exactly is simple and elegant about it? Have you looked into how much tooling is necessary everywhere in unix to make it work? It's insane. It has a huge footprint and it does not provide standardized APIs to make it work for non covered cases (the best we have is pthread_atfork which is not portable).

Fork is simple, but not easy.

Re: Fork() without exec() is dangerous in large programs

#46
post #45

Earlier quoted context omitted.

> It is true that fork(2) is simple and elegant design What exactly is simple and elegant about it? Have you looked into how much tooling is necessary everywhere in unix to make it work? It's insane. It has a huge footprint and it does not provide standardized APIs to make it work for non covered cases (the best we have is pthread_atfork which is not portable).

Fork is simple, but not easy.

What makes for simple? I really need to understand this. I implemented fork many years ago for a university operating system and nothing about either the implementation nor the usage is simple. I use fork on a daily basis and the POSIX version of it is insanely complex for everybody involved.

Re: Fork() without exec() is dangerous in large programs

#47
post #20

Earlier quoted context omitted.

Most non-UNIX OSes only have exec(), not fork(). Hence why fork() is just kind-of implemented on their POSIX compatibility layers. In UNIX it is only an issue, because IEEE doesn't want to set in stone in POSIX how threads, signals and processes should interact, due to the way threads were added to UNIX.

Non-unix systems don't have exec; they have spawn.

Yeah, sure. I always think of spawn as a plain wrapper exec/fork, hence why I wrote it like that, but you are right correcting me.

Re: Fork() without exec() is dangerous in large programs

#48
post #37
post #13

Earlier quoted context omitted.

What is dangerous is that the interactions between threads and processes aren't part of POSIX standard and its behavior is OS specific across UNIX implementations. This isn't an issue on non-UNIX OSes.

Pthreads are part of the POSIX standard. Hence the "p". Then there is pipe() and probably some more similar ones.

Then you should read what POSIX says about pthreads, regarding mandatory and optional API support, specially the implementation semantics and UB.

For example, what happens to the interactions of signal handlers semantics and thread scheduling.

Or what happens to the threads when the process does a fork().

Re: Fork() without exec() is dangerous in large programs

#49
I ran into this exact problem recently in a multithreaded Python app and spent two days trying to figure out wtf was going on. The multiprocessing spawn startup mode that was added in 3.4 solves this for most use cases at the expense of a small performance hit. For 2.x you are SOL however.

Re: Fork() without exec() is dangerous in large programs

#50
> How to use fork safely: 1. Only use fork to immediately call exec. 2. Fork a worker at the beginning of your program, before there can be other threads. 3. Only use fork in toy programs.

4. Stop writing broken multithreaded code altogether or if you must at least run an event loop per core/thread and use a wrapper for fork() to put the system into a fork()able state before forking. It's nice and reliable.

Multithreading by itself is just not a high-level concept to be used reliably by programs.

Post reply on HN